add delete file entity
This commit is contained in:
parent
6e63251b27
commit
5e6b554f90
@ -4,6 +4,7 @@
|
|||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include <osgEarthUtil/EarthManipulator>
|
#include <osgEarthUtil/EarthManipulator>
|
||||||
|
|
||||||
@ -144,14 +145,30 @@ void ModelTreeWidget::OnEntityRemoved(Entity* entity) {
|
|||||||
void ModelTreeWidget::contextMenuEvent(QContextMenuEvent* event) {
|
void ModelTreeWidget::contextMenuEvent(QContextMenuEvent* event) {
|
||||||
QTreeWidgetItem* item = itemAt(event->pos());
|
QTreeWidgetItem* item = itemAt(event->pos());
|
||||||
if (nullptr != item) {
|
if (nullptr != item) {
|
||||||
QVariant value = item->data(0, E_Entity);
|
// Try entity menu first
|
||||||
if (!value.isValid()) {
|
QVariant valueEntity = item->data(0, E_Entity);
|
||||||
LOG_WARN("unknown data E_Entity");
|
if (valueEntity.isValid()) {
|
||||||
|
Entity* entity = valueEntity.value<Entity*>();
|
||||||
|
PopupEntityMenu(event, entity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity* entity = value.value<Entity*>();
|
// Then file entry menu
|
||||||
PopupEntityMenu(event, entity);
|
QVariant valueEntry = item->data(0, E_FileEntry);
|
||||||
|
if (valueEntry.isValid()) {
|
||||||
|
auto* entry = valueEntry.value<FileEntry*>();
|
||||||
|
QMenu menu(this);
|
||||||
|
QAction* deleteAction = new QAction(tr("Delete File"), this);
|
||||||
|
menu.addAction(deleteAction);
|
||||||
|
connect(deleteAction, &QAction::triggered, [this, entry]() {
|
||||||
|
OnDeleteFileEntry(entry);
|
||||||
|
});
|
||||||
|
menu.exec(event->globalPos());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, show nothing for group/root
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
QMenu menu(this);
|
QMenu menu(this);
|
||||||
@ -301,6 +318,37 @@ void ModelTreeWidget::OnDeleteEntity(Entity* entity) {
|
|||||||
entity->Destory();
|
entity->Destory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelTreeWidget::OnDeleteFileEntry(FileEntry* entry) {
|
||||||
|
if (!entry) {
|
||||||
|
LOG_WARN("OnDeleteFileEntry: entry is nullptr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto workspace = WorkSpaceManager::Get().GetCurrent();
|
||||||
|
if (!workspace) {
|
||||||
|
LOG_WARN("OnDeleteFileEntry: workspace is nullptr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confirm deletion of the workspace-managed item (non-destructive to physical file)
|
||||||
|
auto res = QMessageBox::question(this, tr("Confirm"), tr("Delete this file entry from workspace?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||||
|
if (res != QMessageBox::Yes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = workspace->RemoveFileEntry(entry->GetType(), entry);
|
||||||
|
if (!ok) {
|
||||||
|
QMessageBox::warning(this, tr("Prompt"), tr("Delete failed"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear property panel to avoid showing stale info of deleted item
|
||||||
|
QVariant v;
|
||||||
|
v.setValue(workspace);
|
||||||
|
emit WorkSpaceChange(v);
|
||||||
|
}
|
||||||
|
|
||||||
void ModelTreeWidget::PopupEntityMenu(QContextMenuEvent* event, Entity* entity) {
|
void ModelTreeWidget::PopupEntityMenu(QContextMenuEvent* event, Entity* entity) {
|
||||||
QMenu menu(this);
|
QMenu menu(this);
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,7 @@ protected:
|
|||||||
class SceneComponent* OnAddComponent(const QString& typeName, class Entity* entity);
|
class SceneComponent* OnAddComponent(const QString& typeName, class Entity* entity);
|
||||||
|
|
||||||
void OnDeleteEntity(class Entity* entity);
|
void OnDeleteEntity(class Entity* entity);
|
||||||
|
void OnDeleteFileEntry(class FileEntry* entry);
|
||||||
|
|
||||||
void PopupEntityMenu(QContextMenuEvent* event, class Entity* entity);
|
void PopupEntityMenu(QContextMenuEvent* event, class Entity* entity);
|
||||||
|
|
||||||
|
|||||||
@ -381,3 +381,66 @@ void WorkSpace::NotifyFileEntryUpdated(FileEntryType type, std::shared_ptr<FileE
|
|||||||
++filesSeq_;
|
++filesSeq_;
|
||||||
emit FilesChanged(type, fileEntry);
|
emit FilesChanged(type, fileEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 删除指定指针的文件条目(不删除物理文件,仅移出工作空间管理)
|
||||||
|
bool WorkSpace::RemoveFileEntry(FileEntryType type, FileEntry* entry) {
|
||||||
|
if (!entry) {
|
||||||
|
LOG_WARN("RemoveFileEntry: entry is nullptr");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto it = files_.find(type);
|
||||||
|
if (it == files_.end()) {
|
||||||
|
LOG_WARN("RemoveFileEntry: type not found: {}", FileEntryTypeToString(type));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto& vec = it->second;
|
||||||
|
auto pos = std::find_if(vec.begin(), vec.end(), [entry](const std::shared_ptr<FileEntry>& sp){ return sp.get() == entry; });
|
||||||
|
if (pos == vec.end()) {
|
||||||
|
LOG_WARN("RemoveFileEntry: entry not found in type: {}", FileEntryTypeToString(type));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vec.erase(pos);
|
||||||
|
++filesSeq_;
|
||||||
|
emit FilesChanged(type, nullptr);
|
||||||
|
LOG_INFO("Removed file entry of type: {}", FileEntryTypeToString(type));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按索引删除文件条目
|
||||||
|
bool WorkSpace::RemoveFileEntryAt(FileEntryType type, int index) {
|
||||||
|
auto it = files_.find(type);
|
||||||
|
if (it == files_.end()) {
|
||||||
|
LOG_WARN("RemoveFileEntryAt: type not found: {}", FileEntryTypeToString(type));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto& vec = it->second;
|
||||||
|
if (index < 0 || index >= static_cast<int>(vec.size())) {
|
||||||
|
LOG_WARN("RemoveFileEntryAt: invalid index {} for type {}", index, FileEntryTypeToString(type));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vec.erase(vec.begin() + index);
|
||||||
|
++filesSeq_;
|
||||||
|
emit FilesChanged(type, nullptr);
|
||||||
|
LOG_INFO("Removed file entry at index {} for type {}", index, FileEntryTypeToString(type));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按文件名删除文件条目(匹配工作空间内记录的文件名)
|
||||||
|
bool WorkSpace::RemoveFileEntryByName(FileEntryType type, const QString& fileName) {
|
||||||
|
auto it = files_.find(type);
|
||||||
|
if (it == files_.end()) {
|
||||||
|
LOG_WARN("RemoveFileEntryByName: type not found: {}", FileEntryTypeToString(type));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto& vec = it->second;
|
||||||
|
auto pos = std::find_if(vec.begin(), vec.end(), [&fileName](const std::shared_ptr<FileEntry>& sp){ return sp && sp->GetFileName() == fileName; });
|
||||||
|
if (pos == vec.end()) {
|
||||||
|
LOG_WARN("RemoveFileEntryByName: file not found: {}", fileName.toUtf8().constData());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vec.erase(pos);
|
||||||
|
++filesSeq_;
|
||||||
|
emit FilesChanged(type, nullptr);
|
||||||
|
LOG_INFO("Removed file entry by name: {} for type {}", fileName.toUtf8().constData(), FileEntryTypeToString(type));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@ -68,12 +68,17 @@ public:
|
|||||||
// New unified file entry management
|
// New unified file entry management
|
||||||
FileEntryResult SetFileEntry(std::shared_ptr<FileEntry> fileEntry, bool is_copy = true);
|
FileEntryResult SetFileEntry(std::shared_ptr<FileEntry> fileEntry, bool is_copy = true);
|
||||||
|
|
||||||
std::vector<std::shared_ptr<FileEntry>> GetFileEntries(FileEntryType type) const;
|
std::vector<std::shared_ptr<FileEntry>> GetFileEntries(FileEntryType type) const;
|
||||||
|
|
||||||
// Manage grouped file entries
|
// Manage grouped file entries
|
||||||
bool SetFileEntryCount(FileEntryType type, int count);
|
bool SetFileEntryCount(FileEntryType type, int count);
|
||||||
QString GetFileEntryAbsPath(FileEntryType type, int index) const;
|
QString GetFileEntryAbsPath(FileEntryType type, int index) const;
|
||||||
|
|
||||||
|
// Remove file entries
|
||||||
|
bool RemoveFileEntry(FileEntryType type, class FileEntry* entry);
|
||||||
|
bool RemoveFileEntryAt(FileEntryType type, int index);
|
||||||
|
bool RemoveFileEntryByName(FileEntryType type, const QString& fileName);
|
||||||
|
|
||||||
inline void SetHomeViewpoint(const osgEarth::Viewpoint& viewpoint) {
|
inline void SetHomeViewpoint(const osgEarth::Viewpoint& viewpoint) {
|
||||||
homeViewpoint_ = viewpoint;
|
homeViewpoint_ = viewpoint;
|
||||||
homeViewpoint_.setHeading(0.0); // Ensure heading is set to 0.0
|
homeViewpoint_.setHeading(0.0); // Ensure heading is set to 0.0
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user