diff --git a/src/ui/DockWidget.cpp b/src/ui/DockWidget.cpp index 3f3714cc..e575cb53 100644 --- a/src/ui/DockWidget.cpp +++ b/src/ui/DockWidget.cpp @@ -25,7 +25,7 @@ DockWidget::DockWidget(const QString& title, QWidget* parent) if (nullptr != windowManagerMenu) { windowManagerMenu->AddDockWidget(this); } - // 同步到可视的 WindowManagerMenu 列表(如果存在) + // Also register with visible WindowManagerMenu list if available if (auto* listMenu = MainFrame::Get().GetMenuManager("window_manager")) { listMenu->AddDockWidget(this); } @@ -41,7 +41,7 @@ DockWidget::DockWidget(QWidget* parent) if (nullptr != windowManagerMenu) { windowManagerMenu->AddDockWidget(this); } - // 同步到可视的 WindowManagerMenu 列表(如果存在) + // Also register with visible WindowManagerMenu list if available if (auto* listMenu = MainFrame::Get().GetMenuManager("window_manager")) { listMenu->AddDockWidget(this); } diff --git a/src/ui/Menu/FileManagerMenu.cpp b/src/ui/Menu/FileManagerMenu.cpp index ad9b8f4f..7b480da6 100644 --- a/src/ui/Menu/FileManagerMenu.cpp +++ b/src/ui/Menu/FileManagerMenu.cpp @@ -52,12 +52,28 @@ void FileManagerMenu::NewWorkSpace() { } void FileManagerMenu::OpenWorkSpace() { + // Select workspace file first QString fileName = QFileDialog::getOpenFileName(&MainFrame::Get(), QObject::tr("Open Workspace"), Application::GetWorkSpacePath(), QObject::tr("Dyt Files (*.dyt)")); if (fileName.isEmpty()) { return; } + // After a valid file path is selected, prompt to save/unload current workspace + auto* current = WorkSpaceManager::Get().GetCurrent(); + if (current) { + QMessageBox::StandardButton ret = QMessageBox::question( + &MainFrame::Get(), QObject::tr("warning"), QObject::tr("save current workspace?"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + if (ret == QMessageBox::Cancel) { + return; + } + if (ret == QMessageBox::Yes) { + SaveWorkSpace(); + } + current->Unlaod(); + } + LOG_INFO("open workspace: {}", fileName.toLocal8Bit().constData()); emit LoadDyt(fileName); } diff --git a/src/ui/Menu/SystemManagerMenu.cpp b/src/ui/Menu/SystemManagerMenu.cpp index aaa77573..af978728 100644 --- a/src/ui/Menu/SystemManagerMenu.cpp +++ b/src/ui/Menu/SystemManagerMenu.cpp @@ -31,26 +31,44 @@ void SystemManagerMenu::AddDockWidget(class DockWidget* dockWidget) { } ); action->setCheckable(true); - // 勾选状态应与可见状态一致 + // Keep action checked state consistent with dock visibility action->setChecked(dockWidget->isVisible()); - // 绑定 dock 到 action,便于打开菜单时同步状态 + // Bind dock widget to action via data for state sync action->setData(QVariant::fromValue(dockWidget)); connect(action, &QAction::triggered, [dockWidget, action]() { dockWidget->setVisible(action->isChecked()); } ); - // 同步可见性变化到勾选状态 + // Sync visibility changes to action checked state connect(dockWidget, &DockWidget::visibilityChanged, [action](bool visible) { action->setChecked(visible); }); connect(dockWidget, &DockWidget::signalClose, [action]() { action->setChecked(false); }); + // Remove action when associated DockWidget is destroyed + connect(dockWidget, &QObject::destroyed, this, [this, dockWidget]() { + RemoveDockWidget(dockWidget); + }); windowManagerMenu_->addAction(action); } void SystemManagerMenu::RemoveDockWidget(class DockWidget* dockWidget) { - + if (!windowManagerMenu_) { + return; + } + const auto actions = windowManagerMenu_->actions(); + for (QAction* act : actions) { + QVariant v = act->data(); + if (v.isValid()) { + DockWidget* dock = v.value(); + if (dock == dockWidget) { + windowManagerMenu_->removeAction(act); + act->deleteLater(); + break; + } + } + } } void SystemManagerMenu::InitConnect() { @@ -71,9 +89,9 @@ void SystemManagerMenu::OnExit() { } void SystemManagerMenu::OnWindowManagerMenu() { - // ���Ӵ��ڹ����˵� + // Add window manager menu LOG_INFO("add window manager menu"); - // 打开菜单前,同步所有条目的勾选状态与当前 dock 可见性 + // Before opening, sync action checked state with current dock visibility for (QAction* act : windowManagerMenu_->actions()) { QVariant v = act->data(); if (v.isValid()) { diff --git a/src/ui/Menu/WindowManagerMenu.cpp b/src/ui/Menu/WindowManagerMenu.cpp index 73ea2617..1346cbe6 100644 --- a/src/ui/Menu/WindowManagerMenu.cpp +++ b/src/ui/Menu/WindowManagerMenu.cpp @@ -14,8 +14,7 @@ WindowManagerMenu::WindowManagerMenu(QWidget* parent) : QWidget(parent) , ui(new Ui::WindowManagerMenu) { ui->setupUi(this); - - + connect(ui->listWidget, &QListWidget::itemClicked, this, &WindowManagerMenu::OnItemClicked); } WindowManagerMenu::~WindowManagerMenu() { @@ -33,24 +32,43 @@ void WindowManagerMenu::AddDockWidget(DockWidget* dockWidget) { item->setText(title); } ); - // 初始勾选状态与 dock 的可见性同步 + // Initialize check state to match dock visibility item->setCheckState(dockWidget->isVisible() ? Qt::Checked : Qt::Unchecked); - connect(ui->listWidget, &QListWidget::itemClicked, [](QListWidgetItem* item) { - bool checked = !(item->checkState() == Qt::Checked); - item->setCheckState(checked ? Qt::Checked : Qt::Unchecked); - item->data(DockWidgetRole).value()->setVisible(checked); - }); item->setData(DockWidgetRole, QVariant::fromValue(dockWidget)); - // 同步 dock 可见性变化到勾选状态 + // Sync dock visibility changes to check state connect(dockWidget, &DockWidget::visibilityChanged, [item](bool visible) { item->setCheckState(visible ? Qt::Checked : Qt::Unchecked); }); connect(dockWidget, &DockWidget::signalClose, [this, item]() { item->setCheckState(Qt::Unchecked); }); + // Remove the corresponding item when the DockWidget is destroyed + connect(dockWidget, &QObject::destroyed, this, [this, dockWidget]() { + RemoveDockWidget(dockWidget); + }); ui->listWidget->addItem(item); } void WindowManagerMenu::RemoveDockWidget(class DockWidget* dockWidget) { - + if (!ui || !ui->listWidget) { + return; + } + for (int i = 0; i < ui->listWidget->count(); ++i) { + QListWidgetItem* item = ui->listWidget->item(i); + DockWidget* dock = item->data(DockWidgetRole).value(); + if (dock == dockWidget) { + // Remove and delete the list item + delete ui->listWidget->takeItem(i); + break; + } + } +} + +void WindowManagerMenu::OnItemClicked(QListWidgetItem* item) { + bool checked = !(item->checkState() == Qt::Checked); + item->setCheckState(checked ? Qt::Checked : Qt::Unchecked); + DockWidget* dock = item->data(DockWidgetRole).value(); + if (dock) { + dock->setVisible(checked); + } } diff --git a/src/ui/Menu/WindowManagerMenu.h b/src/ui/Menu/WindowManagerMenu.h index 586e2dad..74e8375c 100644 --- a/src/ui/Menu/WindowManagerMenu.h +++ b/src/ui/Menu/WindowManagerMenu.h @@ -8,6 +8,8 @@ namespace Ui { class WindowManagerMenu; } +class QListWidgetItem; + class WindowManagerMenu : public QWidget { Q_OBJECT @@ -23,4 +25,6 @@ protected: private: Ui::WindowManagerMenu* ui; +private slots: + void OnItemClicked(QListWidgetItem* item); }; \ No newline at end of file diff --git a/src/workspace/WorkSpaceManager.cpp b/src/workspace/WorkSpaceManager.cpp index c059f883..4191ffa2 100644 --- a/src/workspace/WorkSpaceManager.cpp +++ b/src/workspace/WorkSpaceManager.cpp @@ -161,7 +161,9 @@ void WorkSpaceManager::SetCurrent(WorkSpace* workspace) { } if (nullptr != current_) { + // Ensure previous workspace is properly ended and unloaded current_->End(); + current_->Unlaod(); } current_ = workspace; workspace->SetActiveScene(scene_);