#include "nmVTKViewCommandController.h" #include "nmWxVTKRenderContainerWidget.h" #include #include #include #include #include #include namespace { // 图标沿用现有部署目录,命令控制器不复制或拥有图片资源。 QString commandIconPath(const QString& sFileName) { const QString sApplicationDir = QCoreApplication::applicationDirPath(); return sApplicationDir.section('/', 0, -2) + "/Res/Icon/" + sFileName; } } nmVTKViewCommandController::nmVTKViewCommandController( nmWxVTKRenderContainerWidget* pContainer, QObject* pParent) : QObject(pParent), m_pContainer(pContainer), m_eCapabilities(0), m_bViewAvailable(false) { for(int nIndex = 0; nIndex < ViewCommandCount; ++nIndex) { m_pActions[nIndex] = NULL; } // QAction 只在构造阶段创建一次,后续所有菜单和工具栏复用这些实例。 createAction(ViewCommand_ZoomIn, tr("Zoom In"), "ZoomIn.png", SLOT(zoomIn())); createAction(ViewCommand_ZoomOut, tr("Zoom Out"), "ZoomOut.png", SLOT(zoomOut())); createAction(ViewCommand_Fit, tr("Fit to Window"), "ZoomSelfAdaptation.png", SLOT(fitView())); createAction(ViewCommand_Top, tr("Top View"), "Map2D.png", SLOT(setTopView())); createAction(ViewCommand_Front, tr("Front View"), QString(), SLOT(setFrontView())); createAction(ViewCommand_Right, tr("Right View"), QString(), SLOT(setRightView())); createAction(ViewCommand_Isometric, tr("Isometric View"), QString(), SLOT(setIsometricView())); createAction(ViewCommand_ResetRotationCenter, tr("Reset Rotation Center"), QString(), SLOT(resetRotationCenter())); createAction(ViewCommand_SaveImage, tr("Save as Image"), "SaveImg.png", SLOT(saveImage())); createAction(ViewCommand_CopyImage, tr("Copy Image"), "Copy.png", SLOT(copyImage())); createAction(ViewCommand_Print, tr("Print"), "Print.png", SLOT(printImage())); createAction(ViewCommand_PrintPreview, tr("Print Preview"), "PrePrint.png", SLOT(printPreview())); } nmVTKViewCommandController::~nmVTKViewCommandController() { // QAction 由 QObject 父子关系释放;这里只解除非所有权容器引用。 m_pContainer = NULL; } void nmVTKViewCommandController::setCapabilities(ViewCommands eCommands) { m_eCapabilities = eCommands; updateActionStates(); } nmVTKViewCommandController::ViewCommands nmVTKViewCommandController::getCapabilities() const { return m_eCapabilities; } QAction* nmVTKViewCommandController::getAction( ViewCommand eCommand) const { const int nIndex = actionIndex(eCommand); return nIndex >= 0 ? m_pActions[nIndex] : NULL; } void nmVTKViewCommandController::populateToolBar(QToolBar* pToolBar) const { if(pToolBar == NULL) { return; } const ViewCommand eNavigationCommands[] = { ViewCommand_ZoomIn, ViewCommand_ZoomOut, ViewCommand_Fit, ViewCommand_Top, ViewCommand_Front, ViewCommand_Right, ViewCommand_Isometric, ViewCommand_ResetRotationCenter }; bool bHasNavigation = false; for(int nIndex = 0; nIndex < 8; ++nIndex) { if(supports(eNavigationCommands[nIndex])) { pToolBar->addAction(getAction(eNavigationCommands[nIndex])); bHasNavigation = true; } } // 保存和打印只进入右键菜单;复制是适合高频使用的唯一输出工具栏命令。 if(supports(ViewCommand_CopyImage)) { if(bHasNavigation) { pToolBar->addSeparator(); } pToolBar->addAction(getAction(ViewCommand_CopyImage)); } } void nmVTKViewCommandController::populateContextMenu(QMenu* pMenu) const { if(pMenu == NULL) { return; } bool bHasLeadingCommands = false; if(supports(ViewCommand_SaveImage)) { pMenu->addAction(getAction(ViewCommand_SaveImage)); bHasLeadingCommands = true; } if(supports(ViewCommand_CopyImage)) { pMenu->addAction(getAction(ViewCommand_CopyImage)); bHasLeadingCommands = true; } const ViewCommand eViewCommands[] = { ViewCommand_ZoomIn, ViewCommand_ZoomOut, ViewCommand_Fit, ViewCommand_Top, ViewCommand_Front, ViewCommand_Right, ViewCommand_Isometric, ViewCommand_ResetRotationCenter }; bool bHasViewCommands = false; for(int nIndex = 0; nIndex < 8; ++nIndex) { bHasViewCommands = bHasViewCommands || supports(eViewCommands[nIndex]); } if(bHasViewCommands) { if(bHasLeadingCommands) { pMenu->addSeparator(); } QMenu* pViewMenu = pMenu->addMenu(tr("View")); for(int nIndex = 0; nIndex < 8; ++nIndex) { if(supports(eViewCommands[nIndex])) { pViewMenu->addAction(getAction(eViewCommands[nIndex])); } } bHasLeadingCommands = true; } // 扩展项由业务层直接追加;若存在,则在前后自动补齐分隔线。 const int nActionCount = pMenu->actions().size(); emit contextMenuAboutToShow(pMenu); const QList listActions = pMenu->actions(); const bool bHasExtension = listActions.size() > nActionCount; if(bHasExtension && bHasLeadingCommands) { pMenu->insertSeparator(listActions.at(nActionCount)); } const bool bHasPrint = supports(ViewCommand_Print) || supports(ViewCommand_PrintPreview); if(bHasPrint && (bHasLeadingCommands || bHasExtension)) { pMenu->addSeparator(); } if(supports(ViewCommand_Print)) { pMenu->addAction(getAction(ViewCommand_Print)); } if(supports(ViewCommand_PrintPreview)) { pMenu->addAction(getAction(ViewCommand_PrintPreview)); } } void nmVTKViewCommandController::setViewAvailable(bool bAvailable) { m_bViewAvailable = bAvailable; updateActionStates(); } bool nmVTKViewCommandController::isViewAvailable() const { return m_bViewAvailable; } QAction* nmVTKViewCommandController::createAction( ViewCommand eCommand, const QString& sText, const QString& sIconFile, const char* pSlot) { const int nIndex = actionIndex(eCommand); if(nIndex < 0 || m_pActions[nIndex] != NULL) { return NULL; } QAction* pAction = sIconFile.isEmpty() ? new QAction(sText, this) : new QAction(QIcon(commandIconPath(sIconFile)), sText, this); pAction->setToolTip(sText); pAction->setEnabled(false); if(m_pContainer != NULL && pSlot != NULL) { connect(pAction, SIGNAL(triggered()), m_pContainer, pSlot); } m_pActions[nIndex] = pAction; return pAction; } int nmVTKViewCommandController::actionIndex(ViewCommand eCommand) const { switch(eCommand) { case ViewCommand_ZoomIn: return 0; case ViewCommand_ZoomOut: return 1; case ViewCommand_Fit: return 2; case ViewCommand_Top: return 3; case ViewCommand_Front: return 4; case ViewCommand_Right: return 5; case ViewCommand_Isometric: return 6; case ViewCommand_ResetRotationCenter: return 7; case ViewCommand_SaveImage: return 8; case ViewCommand_CopyImage: return 9; case ViewCommand_Print: return 10; case ViewCommand_PrintPreview: return 11; default: return -1; } } bool nmVTKViewCommandController::supports(ViewCommand eCommand) const { return m_eCapabilities.testFlag(eCommand); } void nmVTKViewCommandController::updateActionStates() { const ViewCommand eCommands[ViewCommandCount] = { ViewCommand_ZoomIn, ViewCommand_ZoomOut, ViewCommand_Fit, ViewCommand_Top, ViewCommand_Front, ViewCommand_Right, ViewCommand_Isometric, ViewCommand_ResetRotationCenter, ViewCommand_SaveImage, ViewCommand_CopyImage, ViewCommand_Print, ViewCommand_PrintPreview }; for(int nIndex = 0; nIndex < ViewCommandCount; ++nIndex) { QAction* pAction = m_pActions[nIndex]; if(pAction != NULL) { const bool bSupported = supports(eCommands[nIndex]); pAction->setVisible(bSupported); pAction->setEnabled(bSupported && m_bViewAvailable); } } }