mirror of
https://github.com/huderlem/porymap.git
synced 2026-06-14 03:40:50 -05:00
Add map list tool tips / copy actions, simplify MapListModel
This commit is contained in:
parent
b230f21e8d
commit
ff04a41db2
|
|
@ -180,6 +180,7 @@ private slots:
|
|||
void duplicate();
|
||||
void setClipboardData(poryjson::Json::object);
|
||||
void setClipboardData(QImage);
|
||||
void setClipboardData(const QString &text);
|
||||
void copy();
|
||||
void paste();
|
||||
|
||||
|
|
@ -350,7 +351,7 @@ private:
|
|||
void openNewMapDialog();
|
||||
void openNewLayoutDialog();
|
||||
void openSubWindow(QWidget * window);
|
||||
void scrollMapList(MapTree *list, QString itemName);
|
||||
void scrollMapList(MapTree *list, const QString &itemName);
|
||||
void scrollMapListToCurrentMap(MapTree *list);
|
||||
void scrollMapListToCurrentLayout(MapTree *list);
|
||||
void resetMapListFilters();
|
||||
|
|
|
|||
|
|
@ -61,15 +61,42 @@ class MapListModel : public QStandardItemModel {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MapListModel(QObject *parent = nullptr) : QStandardItemModel(parent) {};
|
||||
MapListModel(Project *project, QObject *parent = nullptr);
|
||||
~MapListModel() { }
|
||||
|
||||
virtual QModelIndex indexOf(QString id) const = 0;
|
||||
void setActiveItem(const QString &itemName) { this->activeItemName = itemName; }
|
||||
|
||||
virtual QStandardItem *insertMapItem(const QString &mapName, const QString &folderName);
|
||||
virtual QStandardItem *insertMapFolderItem(const QString &folderName);
|
||||
|
||||
virtual QModelIndex indexOf(const QString &itemName) const;
|
||||
virtual void removeItemAt(const QModelIndex &index);
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const = 0;
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const;
|
||||
|
||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
protected:
|
||||
virtual void removeItem(QStandardItem *item) = 0;
|
||||
Project *project;
|
||||
QStandardItem *root = nullptr;
|
||||
|
||||
QString activeItemName;
|
||||
QString folderTypeName;
|
||||
bool sortingEnabled = false;
|
||||
bool editable = false;
|
||||
|
||||
QIcon mapGrayIcon;
|
||||
QIcon mapIcon;
|
||||
QIcon mapEditedIcon;
|
||||
QIcon mapOpenedIcon;
|
||||
QIcon mapFolderIcon;
|
||||
QIcon emptyMapFolderIcon;
|
||||
|
||||
QMap<QString, QStandardItem *> mapFolderItems;
|
||||
QMap<QString, QStandardItem *> mapItems;
|
||||
|
||||
virtual QStandardItem *createMapItem(const QString &mapName, QStandardItem *map = nullptr);
|
||||
virtual QStandardItem *createMapFolderItem(const QString &groupName, QStandardItem *fromItem = nullptr);
|
||||
virtual void removeItem(QStandardItem *item) = 0;
|
||||
};
|
||||
|
||||
class MapGroupModel : public MapListModel {
|
||||
|
|
@ -80,44 +107,20 @@ public:
|
|||
~MapGroupModel() { }
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
QStringList mimeTypes() const override;
|
||||
virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
public:
|
||||
void setMap(QString mapName) { this->openMap = mapName; }
|
||||
|
||||
QStandardItem *createGroupItem(QString groupName, QStandardItem *fromItem = nullptr);
|
||||
QStandardItem *createMapItem(QString mapName, QStandardItem *fromItem = nullptr);
|
||||
|
||||
QStandardItem *insertGroupItem(QString groupName);
|
||||
QStandardItem *insertMapItem(QString mapName, QString groupName);
|
||||
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const override;
|
||||
virtual QModelIndex indexOf(QString mapName) const override;
|
||||
|
||||
void initialize();
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
|
||||
protected:
|
||||
virtual void removeItem(QStandardItem *item) override;
|
||||
void removeItem(QStandardItem *item) override;
|
||||
|
||||
private:
|
||||
friend class MapTree;
|
||||
void updateProject();
|
||||
|
||||
private:
|
||||
Project *project;
|
||||
QStandardItem *root = nullptr;
|
||||
|
||||
QMap<QString, QStandardItem *> groupItems;
|
||||
QMap<QString, QStandardItem *> mapItems;
|
||||
|
||||
QString openMap;
|
||||
|
||||
signals:
|
||||
void dragMoveCompleted();
|
||||
};
|
||||
|
|
@ -131,36 +134,8 @@ public:
|
|||
MapAreaModel(Project *project, QObject *parent = nullptr);
|
||||
~MapAreaModel() {}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
public:
|
||||
void setMap(QString mapName) { this->openMap = mapName; }
|
||||
|
||||
QStandardItem *createAreaItem(QString areaName);
|
||||
QStandardItem *createMapItem(QString mapName);
|
||||
|
||||
QStandardItem *insertAreaItem(QString areaName);
|
||||
QStandardItem *insertMapItem(QString mapName, QString areaName);
|
||||
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const override;
|
||||
virtual QModelIndex indexOf(QString mapName) const override;
|
||||
|
||||
void initialize();
|
||||
|
||||
protected:
|
||||
virtual void removeItem(QStandardItem *item) override;
|
||||
|
||||
private:
|
||||
Project *project;
|
||||
QStandardItem *root = nullptr;
|
||||
|
||||
QMap<QString, QStandardItem *> areaItems;
|
||||
QMap<QString, QStandardItem *> mapItems;
|
||||
|
||||
QString openMap;
|
||||
|
||||
signals:
|
||||
void edited();
|
||||
void removeItem(QStandardItem *item) override;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -174,34 +149,8 @@ public:
|
|||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
public:
|
||||
void setLayout(QString layoutId) { this->openLayout = layoutId; }
|
||||
|
||||
QStandardItem *createLayoutItem(QString layoutId);
|
||||
QStandardItem *createMapItem(QString mapName);
|
||||
|
||||
QStandardItem *insertLayoutItem(QString layoutId);
|
||||
QStandardItem *insertMapItem(QString mapName, QString layoutId);
|
||||
|
||||
virtual QStandardItem *getItem(const QModelIndex &index) const override;
|
||||
virtual QModelIndex indexOf(QString layoutName) const override;
|
||||
|
||||
void initialize();
|
||||
|
||||
protected:
|
||||
virtual void removeItem(QStandardItem *item) override;
|
||||
|
||||
private:
|
||||
Project *project;
|
||||
QStandardItem *root = nullptr;
|
||||
|
||||
QMap<QString, QStandardItem *> layoutItems;
|
||||
QMap<QString, QStandardItem *> mapItems;
|
||||
|
||||
QString openLayout;
|
||||
|
||||
signals:
|
||||
void edited();
|
||||
void removeItem(QStandardItem *item) override;
|
||||
};
|
||||
|
||||
#endif // MAPLISTMODELS_H
|
||||
|
|
|
|||
|
|
@ -956,9 +956,6 @@ bool MainWindow::setLayout(QString layoutId) {
|
|||
logInfo("Switching to layout-only editing mode. Disabling map-related edits.");
|
||||
|
||||
unsetMap();
|
||||
|
||||
layoutTreeModel->setLayout(layoutId);
|
||||
|
||||
refreshMapScene();
|
||||
updateWindowTitle();
|
||||
updateMapList();
|
||||
|
|
@ -1163,7 +1160,7 @@ void MainWindow::clearProjectUI() {
|
|||
Event::clearIcons();
|
||||
}
|
||||
|
||||
void MainWindow::scrollMapList(MapTree *list, QString itemName) {
|
||||
void MainWindow::scrollMapList(MapTree *list, const QString &itemName) {
|
||||
if (!list || itemName.isEmpty())
|
||||
return;
|
||||
auto model = static_cast<FilterChildrenProxyModel*>(list->model());
|
||||
|
|
@ -1208,9 +1205,16 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
|
|||
QAction* addToFolderAction = nullptr;
|
||||
QAction* deleteFolderAction = nullptr;
|
||||
QAction* openItemAction = nullptr;
|
||||
QAction* copyDisplayNameAction = nullptr;
|
||||
QAction* copyToolTipAction = nullptr;
|
||||
|
||||
if (itemType == "map_name") {
|
||||
// Right-clicking on a map.
|
||||
openItemAction = menu.addAction("Open Map");
|
||||
menu.addSeparator();
|
||||
copyDisplayNameAction = menu.addAction("Copy Map Name");
|
||||
copyToolTipAction = menu.addAction("Copy Map ID");
|
||||
menu.addSeparator();
|
||||
connect(menu.addAction("Duplicate Map"), &QAction::triggered, [this, itemName] {
|
||||
auto dialog = new NewMapDialog(this->editor->project, this->editor->project->getMap(itemName), this);
|
||||
dialog->open();
|
||||
|
|
@ -1226,12 +1230,18 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
|
|||
// Right-clicking on a MAPSEC folder
|
||||
addToFolderAction = menu.addAction("Add New Map to Area");
|
||||
menu.addSeparator();
|
||||
copyDisplayNameAction = menu.addAction("Copy Area Name");
|
||||
menu.addSeparator();
|
||||
deleteFolderAction = menu.addAction("Delete Area");
|
||||
if (itemName == this->editor->project->getEmptyMapsecName())
|
||||
deleteFolderAction->setEnabled(false); // Disallow deleting the default name
|
||||
} else if (itemType == "map_layout") {
|
||||
// Right-clicking on a map layout
|
||||
openItemAction = menu.addAction("Open Layout");
|
||||
menu.addSeparator();
|
||||
copyDisplayNameAction = menu.addAction("Copy Layout Name");
|
||||
copyToolTipAction = menu.addAction("Copy Layout ID");
|
||||
menu.addSeparator();
|
||||
connect(menu.addAction("Duplicate Layout"), &QAction::triggered, [this, itemName] {
|
||||
auto layout = this->editor->project->loadLayout(itemName);
|
||||
if (layout) {
|
||||
|
|
@ -1261,8 +1271,21 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
|
|||
deleteFolderAction->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (openItemAction) {
|
||||
connect(openItemAction, &QAction::triggered, [this, index] { openMapListItem(index); });
|
||||
connect(openItemAction, &QAction::triggered, [this, index] {
|
||||
openMapListItem(index);
|
||||
});
|
||||
}
|
||||
if (copyDisplayNameAction) {
|
||||
connect(copyDisplayNameAction, &QAction::triggered, [this, sourceModel, index] {
|
||||
setClipboardData(sourceModel->data(index, Qt::DisplayRole).toString());
|
||||
});
|
||||
}
|
||||
if (copyToolTipAction) {
|
||||
connect(copyToolTipAction, &QAction::triggered, [this, sourceModel, index] {
|
||||
setClipboardData(sourceModel->data(index, Qt::ToolTipRole).toString());
|
||||
});
|
||||
}
|
||||
|
||||
if (menu.actions().length() != 0)
|
||||
|
|
@ -1399,17 +1422,17 @@ void MainWindow::onNewLayoutCreated(Layout *layout) {
|
|||
}
|
||||
|
||||
// Add new layout to the Layouts map list view
|
||||
this->layoutTreeModel->insertLayoutItem(layout->id);
|
||||
this->layoutTreeModel->insertMapFolderItem(layout->id);
|
||||
}
|
||||
|
||||
void MainWindow::onNewMapGroupCreated(const QString &groupName) {
|
||||
// Add new map group to the Groups map list view
|
||||
this->mapGroupModel->insertGroupItem(groupName);
|
||||
this->mapGroupModel->insertMapFolderItem(groupName);
|
||||
}
|
||||
|
||||
void MainWindow::onNewMapSectionCreated(const QString &idName) {
|
||||
// Add new map section to the Areas map list view
|
||||
this->mapAreaModel->insertAreaItem(idName);
|
||||
this->mapAreaModel->insertMapFolderItem(idName);
|
||||
|
||||
// TODO: Refresh Region Map Editor's map section dropdown, if it's open
|
||||
}
|
||||
|
|
@ -1627,28 +1650,28 @@ void MainWindow::openMapListItem(const QModelIndex &index) {
|
|||
}
|
||||
|
||||
void MainWindow::updateMapList() {
|
||||
// Get the name of the open map/layout (or clear the relevant selection if there is none).
|
||||
QString activeItemName;
|
||||
if (this->editor->map) {
|
||||
this->mapGroupModel->setMap(this->editor->map->name());
|
||||
this->groupListProxyModel->layoutChanged();
|
||||
this->mapAreaModel->setMap(this->editor->map->name());
|
||||
this->areaListProxyModel->layoutChanged();
|
||||
activeItemName = this->editor->map->name();
|
||||
} else {
|
||||
this->mapGroupModel->setMap(QString());
|
||||
this->groupListProxyModel->layoutChanged();
|
||||
this->ui->mapList->clearSelection();
|
||||
this->mapAreaModel->setMap(QString());
|
||||
this->areaListProxyModel->layoutChanged();
|
||||
this->ui->areaList->clearSelection();
|
||||
ui->mapList->clearSelection();
|
||||
ui->areaList->clearSelection();
|
||||
|
||||
if (this->editor->layout) {
|
||||
activeItemName = this->editor->layout->id;
|
||||
} else {
|
||||
ui->layoutList->clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
if (this->editor->layout) {
|
||||
this->layoutTreeModel->setLayout(this->editor->layout->id);
|
||||
this->layoutListProxyModel->layoutChanged();
|
||||
} else {
|
||||
this->layoutTreeModel->setLayout(QString());
|
||||
this->layoutListProxyModel->layoutChanged();
|
||||
this->ui->layoutList->clearSelection();
|
||||
}
|
||||
this->mapGroupModel->setActiveItem(activeItemName);
|
||||
this->mapAreaModel->setActiveItem(activeItemName);
|
||||
this->layoutTreeModel->setActiveItem(activeItemName);
|
||||
|
||||
this->groupListProxyModel->layoutChanged();
|
||||
this->areaListProxyModel->layoutChanged();
|
||||
this->layoutListProxyModel->layoutChanged();
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Save_Project_triggered() {
|
||||
|
|
@ -1782,6 +1805,11 @@ void MainWindow::setClipboardData(OrderedJson::object object) {
|
|||
clipboard->setText(newText);
|
||||
}
|
||||
|
||||
void MainWindow::setClipboardData(const QString &text) {
|
||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(text);
|
||||
}
|
||||
|
||||
void MainWindow::setClipboardData(QImage image) {
|
||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setImage(image);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,43 @@ void MapTree::keyPressEvent(QKeyEvent *event) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
MapListModel::MapListModel(Project *project, QObject *parent) : QStandardItemModel(parent) {
|
||||
this->project = project;
|
||||
this->root = invisibleRootItem();
|
||||
|
||||
this->mapGrayIcon = QIcon(QStringLiteral(":/icons/map_grayed.ico"));
|
||||
this->mapIcon = QIcon(QStringLiteral(":/icons/map.ico"));
|
||||
this->mapEditedIcon = QIcon(QStringLiteral(":/icons/map_edited.ico"));
|
||||
this->mapOpenedIcon = QIcon(QStringLiteral(":/icons/map_opened.ico"));
|
||||
|
||||
this->mapFolderIcon.addFile(QStringLiteral(":/icons/folder_closed_map.ico"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
this->mapFolderIcon.addFile(QStringLiteral(":/icons/folder_map.ico"), QSize(), QIcon::Normal, QIcon::On);
|
||||
|
||||
this->emptyMapFolderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
this->emptyMapFolderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On);
|
||||
}
|
||||
|
||||
QStandardItem *MapListModel::getItem(const QModelIndex &index) const {
|
||||
if (index.isValid()) {
|
||||
QStandardItem *item = static_cast<QStandardItem*>(index.internalPointer());
|
||||
if (item)
|
||||
return item;
|
||||
}
|
||||
return this->root;
|
||||
}
|
||||
|
||||
QModelIndex MapListModel::indexOf(const QString &itemName) const {
|
||||
if (this->mapItems.contains(itemName))
|
||||
return this->mapItems.value(itemName)->index();
|
||||
|
||||
if (this->mapFolderItems.contains(itemName))
|
||||
return this->mapFolderItems.value(itemName)->index();
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void MapListModel::removeItemAt(const QModelIndex &index) {
|
||||
QStandardItem *item = this->getItem(index)->child(index.row(), index.column());
|
||||
if (!item)
|
||||
|
|
@ -49,11 +86,89 @@ void MapListModel::removeItemAt(const QModelIndex &index) {
|
|||
} else {
|
||||
// TODO: Because there's no support for deleting maps we can only delete empty folders
|
||||
if (!item->hasChildren()) {
|
||||
this->removeItem(item);
|
||||
removeItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStandardItem *MapListModel::createMapItem(const QString &mapName, QStandardItem *map) {
|
||||
if (!map) map = new QStandardItem;
|
||||
map->setText(mapName);
|
||||
map->setData(mapName, MapListUserRoles::NameRole);
|
||||
map->setData("map_name", MapListUserRoles::TypeRole);
|
||||
map->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemNeverHasChildren);
|
||||
map->setEditable(this->editable); // Will override flags if necessary
|
||||
this->mapItems.insert(mapName, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
QStandardItem *MapListModel::createMapFolderItem(const QString &folderName, QStandardItem *folder) {
|
||||
if (!folder) folder = new QStandardItem;
|
||||
folder->setText(folderName);
|
||||
folder->setData(folderName, MapListUserRoles::NameRole);
|
||||
folder->setData(this->folderTypeName, MapListUserRoles::TypeRole);
|
||||
folder->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
folder->setEditable(this->editable); // Will override flags if necessary
|
||||
this->mapFolderItems.insert(folderName, folder);
|
||||
return folder;
|
||||
}
|
||||
|
||||
QStandardItem *MapListModel::insertMapItem(const QString &mapName, const QString &folderName) {
|
||||
// Disallow adding MAP_DYNAMIC to the map list.
|
||||
if (mapName == this->project->getDynamicMapName())
|
||||
return nullptr;
|
||||
|
||||
QStandardItem *folder = this->mapFolderItems[folderName];
|
||||
if (!folder) folder = insertMapFolderItem(folderName);
|
||||
|
||||
QStandardItem *map = createMapItem(mapName);
|
||||
folder->appendRow(map);
|
||||
if (this->sortingEnabled)
|
||||
this->sort(0, Qt::AscendingOrder);
|
||||
return map;
|
||||
}
|
||||
|
||||
QStandardItem *MapListModel::insertMapFolderItem(const QString &folderName) {
|
||||
QStandardItem *item = createMapFolderItem(folderName);
|
||||
this->root->appendRow(item);
|
||||
if (this->sortingEnabled)
|
||||
this->sort(0, Qt::AscendingOrder);
|
||||
return item;
|
||||
}
|
||||
|
||||
QVariant MapListModel::data(const QModelIndex &index, int role) const {
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
|
||||
const QStandardItem *item = this->getItem(index)->child(row, col);
|
||||
const QString type = item->data(MapListUserRoles::TypeRole).toString();
|
||||
const QString name = item->data(MapListUserRoles::NameRole).toString();
|
||||
|
||||
if (type == "map_name") {
|
||||
// Data for maps in the map list
|
||||
if (role == Qt::DecorationRole) {
|
||||
if (name == this->activeItemName)
|
||||
return this->mapOpenedIcon;
|
||||
|
||||
const Map* map = this->project->mapCache.value(name);
|
||||
if (!map)
|
||||
return this->mapGrayIcon;
|
||||
return map->hasUnsavedChanges() ? this->mapEditedIcon : this->mapIcon;
|
||||
} else if (role == Qt::ToolTipRole) {
|
||||
return this->project->mapNamesToMapConstants.value(name);
|
||||
}
|
||||
} else if (type == this->folderTypeName) {
|
||||
// Data for map folders in the map list
|
||||
if (role == Qt::DecorationRole) {
|
||||
return item->hasChildren() ? this->mapFolderIcon : this->emptyMapFolderIcon;
|
||||
}
|
||||
}
|
||||
return QStandardItemModel::data(index, role);
|
||||
}
|
||||
|
||||
|
||||
|
||||
QWidget *GroupNameDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const {
|
||||
|
|
@ -83,11 +198,15 @@ void GroupNameDelegate::updateEditorGeometry(QWidget *editor, const QStyleOption
|
|||
|
||||
|
||||
|
||||
MapGroupModel::MapGroupModel(Project *project, QObject *parent) : MapListModel(parent) {
|
||||
this->project = project;
|
||||
this->root = this->invisibleRootItem();
|
||||
MapGroupModel::MapGroupModel(Project *project, QObject *parent) : MapListModel(project, parent) {
|
||||
this->folderTypeName = "map_group";
|
||||
this->editable = true;
|
||||
|
||||
initialize();
|
||||
for (const auto &groupName : this->project->groupNames) {
|
||||
for (const auto &mapName : this->project->groupNameToMapNames.value(groupName)) {
|
||||
insertMapItem(mapName, groupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Qt::DropActions MapGroupModel::supportedDropActions() const {
|
||||
|
|
@ -173,7 +292,7 @@ bool MapGroupModel::dropMimeData(const QMimeData *data, Qt::DropAction action, i
|
|||
|
||||
QModelIndex groupIndex = index(row, 0, parentIndex);
|
||||
QStandardItem *groupItem = this->itemFromIndex(groupIndex);
|
||||
createGroupItem(groupName, groupItem);
|
||||
createMapFolderItem(groupName, groupItem);
|
||||
|
||||
for (QString mapName : mapsToMove) {
|
||||
QStandardItem *mapItem = createMapItem(mapName);
|
||||
|
|
@ -251,143 +370,36 @@ void MapGroupModel::updateProject() {
|
|||
this->project->hasUnsavedDataChanges = true;
|
||||
}
|
||||
|
||||
QStandardItem *MapGroupModel::createGroupItem(QString groupName, QStandardItem *group) {
|
||||
if (!group) group = new QStandardItem;
|
||||
group->setText(groupName);
|
||||
group->setData(groupName, MapListUserRoles::NameRole);
|
||||
group->setData("map_group", MapListUserRoles::TypeRole);
|
||||
group->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable);
|
||||
this->groupItems.insert(groupName, group);
|
||||
return group;
|
||||
}
|
||||
|
||||
QStandardItem *MapGroupModel::createMapItem(QString mapName, QStandardItem *map) {
|
||||
if (!map) map = new QStandardItem;
|
||||
map->setData(mapName, MapListUserRoles::NameRole);
|
||||
map->setData("map_name", MapListUserRoles::TypeRole);
|
||||
map->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
|
||||
this->mapItems[mapName] = map;
|
||||
return map;
|
||||
}
|
||||
|
||||
QStandardItem *MapGroupModel::insertGroupItem(QString groupName) {
|
||||
QStandardItem *group = createGroupItem(groupName);
|
||||
this->root->appendRow(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
void MapGroupModel::removeItem(QStandardItem *item) {
|
||||
this->removeRow(item->row());
|
||||
this->updateProject();
|
||||
}
|
||||
|
||||
QStandardItem *MapGroupModel::insertMapItem(QString mapName, QString groupName) {
|
||||
QStandardItem *group = this->groupItems[groupName];
|
||||
if (!group) {
|
||||
group = insertGroupItem(groupName);
|
||||
}
|
||||
QStandardItem *map = createMapItem(mapName);
|
||||
group->appendRow(map);
|
||||
return map;
|
||||
}
|
||||
|
||||
void MapGroupModel::initialize() {
|
||||
this->groupItems.clear();
|
||||
this->mapItems.clear();
|
||||
|
||||
|
||||
for (const auto &groupName : this->project->groupNames) {
|
||||
QStandardItem *group = createGroupItem(groupName);
|
||||
root->appendRow(group);
|
||||
for (const auto &mapName : this->project->groupNameToMapNames.value(groupName)) {
|
||||
group->appendRow(createMapItem(mapName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStandardItem *MapGroupModel::getItem(const QModelIndex &index) const {
|
||||
if (index.isValid()) {
|
||||
QStandardItem *item = static_cast<QStandardItem*>(index.internalPointer());
|
||||
if (item)
|
||||
return item;
|
||||
}
|
||||
return this->root;
|
||||
}
|
||||
|
||||
QModelIndex MapGroupModel::indexOf(QString mapName) const {
|
||||
if (this->mapItems.contains(mapName)) {
|
||||
return this->mapItems[mapName]->index();
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QVariant MapGroupModel::data(const QModelIndex &index, int role) const {
|
||||
if (!index.isValid()) return QVariant();
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
|
||||
if (role == Qt::DecorationRole) {
|
||||
static QIcon mapGrayIcon = QIcon(QStringLiteral(":/icons/map_grayed.ico"));
|
||||
static QIcon mapIcon = QIcon(QStringLiteral(":/icons/map.ico"));
|
||||
static QIcon mapEditedIcon = QIcon(QStringLiteral(":/icons/map_edited.ico"));
|
||||
static QIcon mapOpenedIcon = QIcon(QStringLiteral(":/icons/map_opened.ico"));
|
||||
|
||||
static QIcon mapFolderIcon;
|
||||
static QIcon folderIcon;
|
||||
static bool loaded = false;
|
||||
if (!loaded) {
|
||||
mapFolderIcon.addFile(QStringLiteral(":/icons/folder_closed_map.ico"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
mapFolderIcon.addFile(QStringLiteral(":/icons/folder_map.ico"), QSize(), QIcon::Normal, QIcon::On);
|
||||
folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
QStandardItem *item = this->getItem(index)->child(row, col);
|
||||
QString type = item->data(MapListUserRoles::TypeRole).toString();
|
||||
|
||||
if (type == "map_group") {
|
||||
if (!item->hasChildren()) {
|
||||
return folderIcon;
|
||||
}
|
||||
return mapFolderIcon;
|
||||
} else if (type == "map_name") {
|
||||
QString mapName = item->data(MapListUserRoles::NameRole).toString();
|
||||
if (mapName == this->openMap) {
|
||||
return mapOpenedIcon;
|
||||
}
|
||||
else if (this->project->mapCache.contains(mapName)) {
|
||||
if (this->project->mapCache.value(mapName)->hasUnsavedChanges()) {
|
||||
return mapEditedIcon;
|
||||
}
|
||||
else {
|
||||
return mapIcon;
|
||||
}
|
||||
}
|
||||
return mapGrayIcon;
|
||||
}
|
||||
}
|
||||
else if (role == Qt::DisplayRole) {
|
||||
QStandardItem *item = this->getItem(index)->child(row, col);
|
||||
QString type = item->data(MapListUserRoles::TypeRole).toString();
|
||||
const QStandardItem *item = this->getItem(index)->child(row, col);
|
||||
const QString type = item->data(MapListUserRoles::TypeRole).toString();
|
||||
const QString name = item->data(MapListUserRoles::NameRole).toString();
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (type == "map_name") {
|
||||
return QString("[%1.%2] ").arg(this->getItem(index)->row()).arg(row, 2, 10, QLatin1Char('0')) + item->data(MapListUserRoles::NameRole).toString();
|
||||
return QString("[%1.%2] ").arg(this->getItem(index)->row()).arg(row, 2, 10, QLatin1Char('0')) + name;
|
||||
}
|
||||
else if (type == "map_group") {
|
||||
return item->data(MapListUserRoles::NameRole).toString();
|
||||
else if (type == this->folderTypeName) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return QStandardItemModel::data(index, role);
|
||||
return MapListModel::data(index, role);
|
||||
}
|
||||
|
||||
bool MapGroupModel::setData(const QModelIndex &index, const QVariant &value, int role) {
|
||||
if (role == MapListUserRoles::NameRole && data(index, MapListUserRoles::TypeRole).toString() == "map_group") {
|
||||
// verify uniqueness of new group name
|
||||
// TODO: Check that the name is a valid symbol name (i.e. only word characters, not starting with a number)
|
||||
if (this->project->groupNames.contains(value.toString())) {
|
||||
if (!this->project->isIdentifierUnique(value.toString())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -399,50 +411,15 @@ bool MapGroupModel::setData(const QModelIndex &index, const QVariant &value, int
|
|||
|
||||
|
||||
|
||||
MapAreaModel::MapAreaModel(Project *project, QObject *parent) : MapListModel(parent) {
|
||||
this->project = project;
|
||||
this->root = this->invisibleRootItem();
|
||||
MapAreaModel::MapAreaModel(Project *project, QObject *parent) : MapListModel(project, parent) {
|
||||
this->folderTypeName = "map_section";
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
QStandardItem *MapAreaModel::createAreaItem(QString mapsecName) {
|
||||
QStandardItem *area = new QStandardItem;
|
||||
area->setText(mapsecName);
|
||||
area->setEditable(false);
|
||||
area->setData(mapsecName, MapListUserRoles::NameRole);
|
||||
area->setData("map_section", MapListUserRoles::TypeRole);
|
||||
// group->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
|
||||
this->areaItems.insert(mapsecName, area);
|
||||
return area;
|
||||
}
|
||||
|
||||
QStandardItem *MapAreaModel::createMapItem(QString mapName) {
|
||||
QStandardItem *map = new QStandardItem;
|
||||
map->setText(mapName);
|
||||
map->setEditable(false);
|
||||
map->setData(mapName, MapListUserRoles::NameRole);
|
||||
map->setData("map_name", MapListUserRoles::TypeRole);
|
||||
// map->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
|
||||
this->mapItems.insert(mapName, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
QStandardItem *MapAreaModel::insertAreaItem(QString areaName) {
|
||||
QStandardItem *item = createAreaItem(areaName);
|
||||
this->root->appendRow(item);
|
||||
this->sort(0, Qt::AscendingOrder);
|
||||
return item;
|
||||
}
|
||||
|
||||
QStandardItem *MapAreaModel::insertMapItem(QString mapName, QString areaName) {
|
||||
QStandardItem *area = this->areaItems[areaName];
|
||||
if (!area) {
|
||||
return nullptr;
|
||||
for (const auto &mapName : this->project->mapNames) {
|
||||
insertMapItem(mapName, this->project->mapNameToMapSectionName.value(mapName));
|
||||
}
|
||||
QStandardItem *map = createMapItem(mapName);
|
||||
area->appendRow(map);
|
||||
return map;
|
||||
|
||||
this->sortingEnabled = true;
|
||||
sort(0, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
void MapAreaModel::removeItem(QStandardItem *item) {
|
||||
|
|
@ -450,227 +427,52 @@ void MapAreaModel::removeItem(QStandardItem *item) {
|
|||
this->removeRow(item->row());
|
||||
}
|
||||
|
||||
void MapAreaModel::initialize() {
|
||||
this->areaItems.clear();
|
||||
this->mapItems.clear();
|
||||
|
||||
for (const auto &idName : this->project->mapSectionIdNames) {
|
||||
this->root->appendRow(createAreaItem(idName));
|
||||
}
|
||||
|
||||
LayoutTreeModel::LayoutTreeModel(Project *project, QObject *parent) : MapListModel(project, parent) {
|
||||
this->folderTypeName = "map_layout";
|
||||
|
||||
for (const auto &mapName : this->project->mapNames) {
|
||||
const QString mapsecName = this->project->mapNameToMapSectionName.value(mapName);
|
||||
if (this->areaItems.contains(mapsecName))
|
||||
this->areaItems[mapsecName]->appendRow(createMapItem(mapName));
|
||||
insertMapItem(mapName, this->project->mapNameToLayoutId.value(mapName));
|
||||
}
|
||||
|
||||
this->sort(0, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
QStandardItem *MapAreaModel::getItem(const QModelIndex &index) const {
|
||||
if (index.isValid()) {
|
||||
QStandardItem *item = static_cast<QStandardItem*>(index.internalPointer());
|
||||
if (item)
|
||||
return item;
|
||||
}
|
||||
return this->root;
|
||||
}
|
||||
|
||||
QModelIndex MapAreaModel::indexOf(QString mapName) const {
|
||||
if (this->mapItems.contains(mapName)) {
|
||||
return this->mapItems[mapName]->index();
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QVariant MapAreaModel::data(const QModelIndex &index, int role) const {
|
||||
if (!index.isValid()) return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
|
||||
if (role == Qt::DecorationRole) {
|
||||
static QIcon mapGrayIcon = QIcon(QStringLiteral(":/icons/map_grayed.ico"));
|
||||
static QIcon mapIcon = QIcon(QStringLiteral(":/icons/map.ico"));
|
||||
static QIcon mapEditedIcon = QIcon(QStringLiteral(":/icons/map_edited.ico"));
|
||||
static QIcon mapOpenedIcon = QIcon(QStringLiteral(":/icons/map_opened.ico"));
|
||||
|
||||
static QIcon mapFolderIcon;
|
||||
static QIcon folderIcon;
|
||||
static bool loaded = false;
|
||||
if (!loaded) {
|
||||
mapFolderIcon.addFile(QStringLiteral(":/icons/folder_closed_map.ico"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
mapFolderIcon.addFile(QStringLiteral(":/icons/folder_map.ico"), QSize(), QIcon::Normal, QIcon::On);
|
||||
folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off);
|
||||
folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
QStandardItem *item = this->getItem(index)->child(row, col);
|
||||
QString type = item->data(MapListUserRoles::TypeRole).toString();
|
||||
|
||||
if (type == "map_section") {
|
||||
if (item->hasChildren()) {
|
||||
return mapFolderIcon;
|
||||
}
|
||||
return folderIcon;
|
||||
} else if (type == "map_name") {
|
||||
QString mapName = item->data(MapListUserRoles::NameRole).toString();
|
||||
if (mapName == this->openMap) {
|
||||
return mapOpenedIcon;
|
||||
}
|
||||
else if (this->project->mapCache.contains(mapName)) {
|
||||
if (this->project->mapCache.value(mapName)->hasUnsavedChanges()) {
|
||||
return mapEditedIcon;
|
||||
}
|
||||
else {
|
||||
return mapIcon;
|
||||
}
|
||||
}
|
||||
return mapGrayIcon;
|
||||
}
|
||||
}
|
||||
else if (role == Qt::DisplayRole) {
|
||||
QStandardItem *item = this->getItem(index)->child(row, col);
|
||||
QString type = item->data(MapListUserRoles::TypeRole).toString();
|
||||
|
||||
if (type == "map_section") {
|
||||
return item->data(MapListUserRoles::NameRole).toString();
|
||||
}
|
||||
}
|
||||
|
||||
return QStandardItemModel::data(index, role);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LayoutTreeModel::LayoutTreeModel(Project *project, QObject *parent) : MapListModel(parent) {
|
||||
this->project = project;
|
||||
this->root = this->invisibleRootItem();
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
QStandardItem *LayoutTreeModel::createLayoutItem(QString layoutId) {
|
||||
QStandardItem *layout = new QStandardItem;
|
||||
layout->setText(this->project->mapLayouts[layoutId]->name);
|
||||
layout->setEditable(false);
|
||||
layout->setData(layoutId, MapListUserRoles::NameRole);
|
||||
layout->setData("map_layout", MapListUserRoles::TypeRole);
|
||||
// // group->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
|
||||
this->layoutItems.insert(layoutId, layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
QStandardItem *LayoutTreeModel::createMapItem(QString mapName) {
|
||||
QStandardItem *map = new QStandardItem;
|
||||
map->setText(mapName);
|
||||
map->setEditable(false);
|
||||
map->setData(mapName, MapListUserRoles::NameRole);
|
||||
map->setData("map_name", MapListUserRoles::TypeRole);
|
||||
map->setFlags(Qt::NoItemFlags | Qt::ItemNeverHasChildren);
|
||||
this->mapItems.insert(mapName, map);
|
||||
return map;
|
||||
}
|
||||
|
||||
QStandardItem *LayoutTreeModel::insertLayoutItem(QString layoutId) {
|
||||
QStandardItem *layoutItem = this->createLayoutItem(layoutId);
|
||||
this->root->appendRow(layoutItem);
|
||||
this->sort(0, Qt::AscendingOrder);
|
||||
return layoutItem;
|
||||
}
|
||||
|
||||
QStandardItem *LayoutTreeModel::insertMapItem(QString mapName, QString layoutId) {
|
||||
QStandardItem *layout = nullptr;
|
||||
if (this->layoutItems.contains(layoutId)) {
|
||||
layout = this->layoutItems[layoutId];
|
||||
}
|
||||
else {
|
||||
layout = createLayoutItem(layoutId);
|
||||
this->root->appendRow(layout);
|
||||
}
|
||||
if (!layout) {
|
||||
return nullptr;
|
||||
}
|
||||
QStandardItem *map = createMapItem(mapName);
|
||||
layout->appendRow(map);
|
||||
return map;
|
||||
this->sortingEnabled = true;
|
||||
sort(0, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
void LayoutTreeModel::removeItem(QStandardItem *) {
|
||||
// TODO: Deleting layouts not supported
|
||||
}
|
||||
|
||||
|
||||
void LayoutTreeModel::initialize() {
|
||||
this->layoutItems.clear();
|
||||
this->mapItems.clear();
|
||||
|
||||
for (const auto &layoutId : this->project->layoutIds) {
|
||||
this->root->appendRow(createLayoutItem(layoutId));
|
||||
}
|
||||
|
||||
for (const auto &mapName : this->project->mapNames) {
|
||||
QString layoutId = project->mapNameToLayoutId.value(mapName);
|
||||
if (this->layoutItems.contains(layoutId))
|
||||
this->layoutItems[layoutId]->appendRow(createMapItem(mapName));
|
||||
}
|
||||
|
||||
this->sort(0, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
QStandardItem *LayoutTreeModel::getItem(const QModelIndex &index) const {
|
||||
if (index.isValid()) {
|
||||
QStandardItem *item = static_cast<QStandardItem*>(index.internalPointer());
|
||||
if (item)
|
||||
return item;
|
||||
}
|
||||
return this->root;
|
||||
}
|
||||
|
||||
QModelIndex LayoutTreeModel::indexOf(QString layoutName) const {
|
||||
if (this->layoutItems.contains(layoutName)) {
|
||||
return this->layoutItems[layoutName]->index();
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QVariant LayoutTreeModel::data(const QModelIndex &index, int role) const {
|
||||
if (!index.isValid()) return QVariant();
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
|
||||
if (role == Qt::DecorationRole) {
|
||||
static QIcon mapGrayIcon = QIcon(QStringLiteral(":/icons/map_grayed.ico"));
|
||||
static QIcon mapIcon = QIcon(QStringLiteral(":/icons/map.ico"));
|
||||
static QIcon mapEditedIcon = QIcon(QStringLiteral(":/icons/map_edited.ico"));
|
||||
static QIcon mapOpenedIcon = QIcon(QStringLiteral(":/icons/map_opened.ico"));
|
||||
const QStandardItem *item = this->getItem(index)->child(row, col);
|
||||
const QString type = item->data(MapListUserRoles::TypeRole).toString();
|
||||
const QString name = item->data(MapListUserRoles::NameRole).toString();
|
||||
|
||||
QStandardItem *item = this->getItem(index)->child(row, col);
|
||||
QString type = item->data(MapListUserRoles::TypeRole).toString();
|
||||
if (type == this->folderTypeName) {
|
||||
const Layout* layout = this->project->mapLayouts.value(name);
|
||||
|
||||
if (type == "map_layout") {
|
||||
QString layoutId = item->data(MapListUserRoles::NameRole).toString();
|
||||
if (layoutId == this->openLayout) {
|
||||
return mapOpenedIcon;
|
||||
}
|
||||
else if (this->project->mapLayouts.contains(layoutId)) {
|
||||
if (this->project->mapLayouts.value(layoutId)->hasUnsavedChanges()) {
|
||||
return mapEditedIcon;
|
||||
}
|
||||
else if (!this->project->mapLayouts[layoutId]->loaded) {
|
||||
return mapGrayIcon;
|
||||
}
|
||||
}
|
||||
return mapIcon;
|
||||
if (role == Qt::DecorationRole) {
|
||||
// Map layouts are used as folders, but we display them with the same icons as maps.
|
||||
if (name == this->activeItemName)
|
||||
return this->mapOpenedIcon;
|
||||
|
||||
if (!layout || !layout->loaded)
|
||||
return this->mapGrayIcon;
|
||||
return layout->hasUnsavedChanges() ? this->mapEditedIcon : this->mapIcon;
|
||||
}
|
||||
else if (type == "map_name") {
|
||||
return QVariant();
|
||||
else if (role == Qt::DisplayRole) {
|
||||
// Despite using layout IDs internally, the Layouts map list shows layouts using their file path name.
|
||||
if (layout) return layout->name;
|
||||
} else if (role == Qt::ToolTipRole) {
|
||||
if (layout) return layout->id;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
return QStandardItemModel::data(index, role);
|
||||
return MapListModel::data(index, role);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user