|
|
|
|
|
#include "nmVTKViewCommandController.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmWxVTKRenderContainerWidget.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <QAction>
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
|
|
#include <QIcon>
|
|
|
|
|
|
#include <QList>
|
|
|
|
|
|
#include <QMenu>
|
|
|
|
|
|
#include <QToolBar>
|
|
|
|
|
|
|
|
|
|
|
|
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] = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// QAction 只在构造阶段创建一次,后续所有菜单和工具栏复用这些实例。
|
|
|
|
|
|
createAction(ViewCommand_ZoomIn, tr("Zoom In"), "NmZoomIn.png",
|
|
|
|
|
|
SLOT(zoomIn()));
|
|
|
|
|
|
createAction(ViewCommand_ZoomOut, tr("Zoom Out"), "NmZoomOut.png",
|
|
|
|
|
|
SLOT(zoomOut()));
|
|
|
|
|
|
createAction(ViewCommand_Fit, tr("Fit to Window"),
|
|
|
|
|
|
"NmZoomReset.png", SLOT(fitView()));
|
|
|
|
|
|
createAction(ViewCommand_Top, tr("Top View"), "NmTopView.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"),
|
|
|
|
|
|
"NmCopyGraphic.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 = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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] : nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmVTKViewCommandController::populateToolBar(QToolBar* pToolBar) const
|
|
|
|
|
|
{
|
|
|
|
|
|
if(pToolBar == nullptr) {
|
|
|
|
|
|
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 == nullptr) {
|
|
|
|
|
|
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<QAction*> 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] != nullptr) {
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QAction* pAction = sIconFile.isEmpty()
|
|
|
|
|
|
? new QAction(sText, this)
|
|
|
|
|
|
: new QAction(QIcon(commandIconPath(sIconFile)), sText, this);
|
|
|
|
|
|
pAction->setToolTip(sText);
|
|
|
|
|
|
pAction->setEnabled(false);
|
|
|
|
|
|
if(m_pContainer != nullptr && pSlot != nullptr) {
|
|
|
|
|
|
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 != nullptr) {
|
|
|
|
|
|
const bool bSupported = supports(eCommands[nIndex]);
|
|
|
|
|
|
pAction->setVisible(bSupported);
|
|
|
|
|
|
pAction->setEnabled(bSupported && m_bViewAvailable);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|