You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmRender/nmVTKViewCommandController.cpp

270 lines
8.3 KiB
C++

#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] = 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<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] != 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);
}
}
}