Files
create/src/Mod/TechDraw/Gui/CommandCreateDims.cpp
wandererfan 88c7aac0d9 [TD]fix issues reported by 3d dimension testers
- correct interpretation of True vs Projected

- handle long subelement names in references

- fix "too small" value condition

- better error messages for bad dimension geometry
2023-01-07 16:32:03 -05:00

1707 lines
65 KiB
C++

/***************************************************************************
* Copyright (c) 2014 Luke Parry <l.parry@warwick.ac.uk> *
* Copyright (c) 2022 WandererFan <wandererfan@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QApplication>
#include <QMessageBox>
#include <sstream>
#include <cstdlib>
#include <exception>
#endif //#ifndef _PreComp_
#include <App/Document.h>
#include <App/DocumentObject.h>
#include <Base/Exception.h>
#include <Base/Console.h>
#include <Gui/Action.h>
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Command.h>
#include <Gui/Control.h>
#include <Gui/Document.h>
#include <Gui/MainWindow.h>
#include <Gui/Selection.h>
#include <Gui/SelectionObject.h>
#include <Mod/TechDraw/App/DrawDimHelper.h>
#include <Mod/TechDraw/App/DrawPage.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include <Mod/TechDraw/App/DrawViewDimension.h>
#include <Mod/TechDraw/App/DrawViewPart.h>
#include <Mod/TechDraw/App/Geometry.h>
#include <Mod/TechDraw/App/LandmarkDimension.h>
#include <Mod/TechDraw/App/Preferences.h>
#include "DrawGuiUtil.h"
#include "TaskLinkDim.h"
#include "TaskDimRepair.h"
#include "DimensionValidators.h"
using namespace TechDrawGui;
using namespace TechDraw;
using namespace std;
//===========================================================================
// utility routines
//===========================================================================
//internal functions
bool _checkSelection(Gui::Command* cmd, unsigned maxObjs = 2);
bool _checkDrawViewPart(Gui::Command* cmd);
void execDistance(Gui::Command* cmd);
void execDistanceX(Gui::Command* cmd);
void execDistanceY(Gui::Command* cmd);
void execAngle(Gui::Command* cmd);
void execAngle3Pt(Gui::Command* cmd);
void execRadius(Gui::Command* cmd);
void execDiameter(Gui::Command* cmd);
void execExtent(Gui::Command* cmd, int direction);
DrawViewDimension* dimensionMaker(TechDraw::DrawViewPart* dvp,
std::string dimType,
ReferenceVector references2d,
ReferenceVector references3d);
void positionDimText(DrawViewDimension* dim);
//NOTE: this is not shown in toolbar and doesn't always work right in the menu.
// should be removed.
//===========================================================================
// TechDraw_NewDimension
//===========================================================================
// this is deprecated. use individual add dimension commands.
DEF_STD_CMD_A(CmdTechDrawDimension)
CmdTechDrawDimension::CmdTechDrawDimension()
: Command("TechDraw_Dimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_Dimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_Dimension";
}
void CmdTechDrawDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
}
bool CmdTechDrawDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
//===========================================================================
// TechDraw_RadialGroup
//===========================================================================
DEF_STD_CMD_ACL(CmdTechDrawRadialGroup)
CmdTechDrawRadialGroup::CmdTechDrawRadialGroup()
: Command("TechDraw_RadialGroup")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Radius Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_RadialGroup";
sStatusTip = sToolTipText;
}
void CmdTechDrawRadialGroup::activated(int iMsg)
{
// Base::Console().Message("CMD::LinearGrp - activated(%d)\n", iMsg);
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
if (dlg) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"),
QObject::tr("Close active task dialog and try again."));
return;
}
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
pcAction->setIcon(pcAction->actions().at(iMsg)->icon());
switch(iMsg) {
case 0:
execRadius(this);
break;
case 1:
execDiameter(this);
break;
default:
Base::Console().Message("CMD::RadialGrp - invalid iMsg: %d\n", iMsg);
};
}
Gui::Action * CmdTechDrawRadialGroup::createAction()
{
Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow());
pcAction->setDropDownMenu(true);
applyCommandData(this->className(), pcAction);
QAction* p0 = pcAction->addAction(QString());
p0->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_RadiusDimension"));
p0->setObjectName(QString::fromLatin1("TechDraw_RadiusDimension"));
p0->setWhatsThis(QString::fromLatin1("TechDraw_RadiusDimension"));
QAction* p1 = pcAction->addAction(QString());
p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_DiameterDimension"));
p1->setObjectName(QString::fromLatin1("TechDraw_DiameterDimension"));
p1->setWhatsThis(QString::fromLatin1("TechDraw_DiameterDimension"));
_pcAction = pcAction;
languageChange();
pcAction->setIcon(p0->icon());
int defaultId = 0;
pcAction->setProperty("defaultAction", QVariant(defaultId));
return pcAction;
}
void CmdTechDrawRadialGroup::languageChange()
{
Command::languageChange();
if (!_pcAction)
return;
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
QAction* arc0 = a[0];
arc0->setText(QApplication::translate("CmdTechDrawRadialGroup", "Radius Dimension"));
arc0->setToolTip(QApplication::translate("TechDraw_RadiusDimension", "Insert Radius Dimension"));
arc0->setStatusTip(arc0->toolTip());
QAction* arc1 = a[1];
arc1->setText(QApplication::translate("CmdTechDrawRadialGroup", "Diameter Linear"));
arc1->setToolTip(QApplication::translate("TechDraw_DiameterDimension", "Insert Diameter Dimension"));
arc1->setStatusTip(arc1->toolTip());
}
bool CmdTechDrawRadialGroup::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, false);
return (havePage && haveView);
}
//===========================================================================
// TechDraw_RadiusDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawRadiusDimension)
CmdTechDrawRadiusDimension::CmdTechDrawRadiusDimension()
: Command("TechDraw_RadiusDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Radius Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_RadiusDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_RadiusDimension";
}
void CmdTechDrawRadiusDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
execRadius(this);
}
bool CmdTechDrawRadiusDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
void execRadius(Gui::Command* cmd)
{
bool result = _checkDrawViewPart(cmd);
if (!result) {
QMessageBox::warning( Gui::getMainWindow(),
QObject::tr("Incorrect selection"),
QObject::tr("No View of a Part in selection.") );
return;
}
ReferenceVector references2d;
ReferenceVector references3d;
TechDraw::DrawViewPart* partFeat = TechDraw::getReferencesFromSelection(references2d, references3d);
//Define the geometric configuration required for a radius dimension
StringVector acceptableGeometry( { "Edge" } );
std::vector<int> minimumCounts( { 1 } );
std::vector<DimensionGeometryType> acceptableDimensionGeometrys( { isCircle, isEllipse, isBSplineCircle } );
//what 2d geometry configuration did we receive?
DimensionGeometryType geometryRefs2d = validateDimSelection(references2d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs2d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 2d radius dimension from selection"));
return;
}
//what 3d geometry configuration did we receive?
DimensionGeometryType geometryRefs3d(isInvalid);
if (geometryRefs2d == TechDraw::isViewReference &&
!references3d.empty()) {
geometryRefs3d = validateDimSelection3d(partFeat,
references3d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs3d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 3d radius dimension from selection"));
return;
}
}
//errors and warnings
if (geometryRefs2d == isEllipse ||
geometryRefs3d == isEllipse) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Ellipse Curve Warning"),
QObject::tr("Selected edge is an Ellipse. Radius will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result != QMessageBox::Ok) {
return;
}
}
if (geometryRefs2d == isBSplineCircle ||
geometryRefs3d == isBSplineCircle) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"),
QObject::tr("Selected edge is a BSpline. Radius will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result != QMessageBox::Ok) {
return;
}
}
if (geometryRefs2d == isBSpline ||
geometryRefs3d == isBSpline) {
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("BSpline Curve Error"),
QObject::tr("Selected edge is a BSpline and a radius can not be calculated."));
return;
}
//build the dimension
// DrawViewDimension* dim =
dimensionMaker(partFeat,
"Radius",
references2d,
references3d);
//Horrible hack to force Tree update
double x = partFeat->X.getValue();
partFeat->X.setValue(x);
}
//===========================================================================
// TechDraw_DiameterDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawDiameterDimension)
CmdTechDrawDiameterDimension::CmdTechDrawDiameterDimension()
: Command("TechDraw_DiameterDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Diameter Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_DiameterDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_DiameterDimension";
}
void CmdTechDrawDiameterDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
execDiameter(this);
}
bool CmdTechDrawDiameterDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
void execDiameter(Gui::Command* cmd)
{
bool result = _checkDrawViewPart(cmd);
if (!result) {
QMessageBox::warning( Gui::getMainWindow(),
QObject::tr("Incorrect selection"),
QObject::tr("No View of a Part in selection.") );
return;
}
ReferenceVector references2d;
ReferenceVector references3d;
TechDraw::DrawViewPart* partFeat = TechDraw::getReferencesFromSelection(references2d, references3d);
//Define the geometric configuration required for a diameter dimension
StringVector acceptableGeometry( { "Edge" } );
std::vector<int> minimumCounts( { 1 } );
std::vector<DimensionGeometryType> acceptableDimensionGeometrys( { isCircle, isEllipse, isBSplineCircle } );
//what 2d geometry configuration did we receive?
DimensionGeometryType geometryRefs2d = validateDimSelection(references2d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs2d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 2d diameter dimension from selection"));
return;
}
//what 3d geometry configuration did we receive?
DimensionGeometryType geometryRefs3d(isInvalid);
if (geometryRefs2d == TechDraw::isViewReference &&
!references3d.empty()) {
geometryRefs3d = validateDimSelection3d(partFeat,
references3d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs3d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 3d diameter dimension from selection"));
return;
}
}
//errors and warnings
if (geometryRefs2d == isEllipse ||
geometryRefs3d == isEllipse) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Ellipse Curve Warning"),
QObject::tr("Selected edge is an Ellipse. Diameter will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result != QMessageBox::Ok) {
return;
}
}
if (geometryRefs2d == isBSplineCircle ||
geometryRefs3d == isBSplineCircle) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"),
QObject::tr("Selected edge is a BSpline. Diameter will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result != QMessageBox::Ok) {
return;
}
}
if (geometryRefs2d == isBSpline ||
geometryRefs3d == isBSpline) {
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("BSpline Curve Error"),
QObject::tr("Selected edge is a BSpline and a diameter can not be calculated."));
return;
}
//build the dimension
// DrawViewDimension* dim =
dimensionMaker(partFeat,
"Diameter",
references2d,
references3d);
//Horrible hack to force Tree update
double x = partFeat->X.getValue();
partFeat->X.setValue(x);
}
//===========================================================================
// TechDraw_LinearGroup
//===========================================================================
DEF_STD_CMD_ACL(CmdTechDrawLinearGroup)
CmdTechDrawLinearGroup::CmdTechDrawLinearGroup()
: Command("TechDraw_LinearGroup")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Linear Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_LinearGroup";
sStatusTip = sToolTipText;
}
void CmdTechDrawLinearGroup::activated(int iMsg)
{
// Base::Console().Message("CMD::LinearGrp - activated(%d)\n", iMsg);
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
if (dlg) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"),
QObject::tr("Close active task dialog and try again."));
return;
}
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
pcAction->setIcon(pcAction->actions().at(iMsg)->icon());
switch(iMsg) {
case 0:
execDistance(this);
break;
case 1:
execDistanceX(this);
break;
case 2:
execDistanceY(this);
break;
default:
Base::Console().Message("CMD::LinearGrp - invalid iMsg: %d\n", iMsg);
};
}
Gui::Action * CmdTechDrawLinearGroup::createAction()
{
Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow());
pcAction->setDropDownMenu(true);
applyCommandData(this->className(), pcAction);
QAction* p0 = pcAction->addAction(QString());
p0->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_LengthDimension"));
p0->setObjectName(QString::fromLatin1("TechDraw_LengthDimension"));
p0->setWhatsThis(QString::fromLatin1("TechDraw_LengthDimension"));
QAction* p1 = pcAction->addAction(QString());
p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_HorizontalDimension"));
p1->setObjectName(QString::fromLatin1("TechDraw_HorizontalDimension"));
p1->setWhatsThis(QString::fromLatin1("TechDraw_HorizontalDimension"));
QAction* p2 = pcAction->addAction(QString());
p2->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_VerticalDimension"));
p2->setObjectName(QString::fromLatin1("TechDraw_VerticalDimension"));
p2->setWhatsThis(QString::fromLatin1("TechDraw_VerticalDimension"));
_pcAction = pcAction;
languageChange();
pcAction->setIcon(p0->icon());
int defaultId = 0;
pcAction->setProperty("defaultAction", QVariant(defaultId));
return pcAction;
}
void CmdTechDrawLinearGroup::languageChange()
{
Command::languageChange();
if (!_pcAction)
return;
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
QAction* arc0 = a[0];
arc0->setText(QApplication::translate("CmdTechDrawLinearGroup", "Linear Dimension"));
arc0->setToolTip(QApplication::translate("TechDraw_LengthDimension", "Insert Linear Dimension"));
arc0->setStatusTip(arc0->toolTip()); QAction* arc1 = a[1];
arc1->setText(QApplication::translate("CmdTechDrawLinearGroup", "Horizontal Linear"));
arc1->setToolTip(QApplication::translate("TechDraw_HorizontalLinear", "Insert Horizontal Linear Dimension"));
arc1->setStatusTip(arc1->toolTip());
QAction* arc2 = a[2];
arc2->setText(QApplication::translate("CmdTechDrawLinearGroup", "Vertical Linear"));
arc2->setToolTip(QApplication::translate("TechDraw_VerticalDimension", "Insert Vertical Linear Dimension"));
arc2->setStatusTip(arc2->toolTip());
}
bool CmdTechDrawLinearGroup::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, false);
return (havePage && haveView);
}
//===========================================================================
// TechDraw_LengthDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawLengthDimension)
CmdTechDrawLengthDimension::CmdTechDrawLengthDimension()
: Command("TechDraw_LengthDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Length Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_LengthDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_LengthDimension";
}
void CmdTechDrawLengthDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
}
bool CmdTechDrawLengthDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
void execDistance(Gui::Command* cmd)
{
bool result = _checkDrawViewPart(cmd);
if (!result) {
QMessageBox::warning( Gui::getMainWindow(),
QObject::tr("Incorrect selection"),
QObject::tr("No View of a Part in selection.") );
return;
}
ReferenceVector references2d;
ReferenceVector references3d;
TechDraw::DrawViewPart* partFeat = TechDraw::getReferencesFromSelection(references2d, references3d);
//Define the geometric configuration required for a length dimension
StringVector acceptableGeometry( { "Edge", "Vertex" } );
std::vector<int> minimumCounts( { 1, 2 } );
std::vector<DimensionGeometryType> acceptableDimensionGeometrys( { isVertical, isHorizontal, isDiagonal } );
//what 2d geometry configuration did we receive?
DimensionGeometryType geometryRefs2d = validateDimSelection(references2d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs2d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 2d linear dimension from selection"));
return;
}
//what 3d geometry configuration did we receive?
DimensionGeometryType geometryRefs3d;
if (geometryRefs2d == TechDraw::isViewReference &&
!references3d.empty()) {
geometryRefs3d = validateDimSelection3d(partFeat,
references3d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs3d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 3d linear dimension from selection"));
return;
}
}
//build the dimension
DrawViewDimension* dim = dimensionMaker(partFeat,
"Distance",
references2d,
references3d);
//position the Dimension text on the view
positionDimText(dim);
//Horrible hack to force Tree update (claimChildren)
double x = partFeat->X.getValue();
partFeat->X.setValue(x);
}
//===========================================================================
// TechDraw_HorizontalDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawHorizontalDimension)
CmdTechDrawHorizontalDimension::CmdTechDrawHorizontalDimension()
: Command("TechDraw_HorizontalDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Horizontal Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_HorizontalDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_HorizontalDimension";
sAccel = "SHIFT+H";
}
void CmdTechDrawHorizontalDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
execDistanceX(this);
}
bool CmdTechDrawHorizontalDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
void execDistanceX(Gui::Command* cmd)
{
bool result = _checkDrawViewPart(cmd);
if (!result) {
QMessageBox::warning( Gui::getMainWindow(),
QObject::tr("Incorrect selection"),
QObject::tr("No View of a Part in selection.") );
return;
}
ReferenceVector references2d;
ReferenceVector references3d;
TechDraw::DrawViewPart* partFeat = TechDraw::getReferencesFromSelection(references2d, references3d);
//Define the geometric configuration required for a length dimension
StringVector acceptableGeometry( { "Edge", "Vertex" } );
std::vector<int> minimumCounts( { 1, 2 } );
std::vector<DimensionGeometryType> acceptableDimensionGeometrys( { isHorizontal, isDiagonal } );
//what 2d geometry configuration did we receive?
DimensionGeometryType geometryRefs2d = validateDimSelection(references2d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs2d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 2d horizontal dimension from selection"));
return;
}
//what 3d geometry configuration did we receive?
DimensionGeometryType geometryRefs3d;
if (geometryRefs2d == TechDraw::isViewReference &&
!references3d.empty()) {
geometryRefs3d = validateDimSelection3d(partFeat,
references3d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if (geometryRefs3d == TechDraw::isInvalid) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 3d horizontal dimension from selection"));
return;
}
}
//build the dimension
DrawViewDimension* dim = dimensionMaker(partFeat,
"DistanceX",
references2d,
references3d);
//position the Dimension text on the view
positionDimText(dim);
//Horrible hack to force Tree update (claimChildren)
double x = partFeat->X.getValue();
partFeat->X.setValue(x);
}
//===========================================================================
// TechDraw_VerticalDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawVerticalDimension)
CmdTechDrawVerticalDimension::CmdTechDrawVerticalDimension()
: Command("TechDraw_VerticalDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Vertical Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_VerticalDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_VerticalDimension";
sAccel = "SHIFT+V";
}
void CmdTechDrawVerticalDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
execDistanceY(this);
}
bool CmdTechDrawVerticalDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
void execDistanceY(Gui::Command* cmd)
{
bool result = _checkDrawViewPart(cmd);
if (!result) {
QMessageBox::warning( Gui::getMainWindow(),
QObject::tr("Incorrect selection"),
QObject::tr("No View of a Part in selection.") );
return;
}
ReferenceVector references2d;
ReferenceVector references3d;
TechDraw::DrawViewPart* partFeat = TechDraw::getReferencesFromSelection(references2d, references3d);
//Define the geometric configuration required for a length dimension
StringVector acceptableGeometry( { "Edge", "Vertex" } );
std::vector<int> minimumCounts( { 1, 2 } );
std::vector<DimensionGeometryType> acceptableDimensionGeometrys( { isVertical, isDiagonal } );
//what 2d geometry configuration did we receive?
DimensionGeometryType geometryRefs2d = validateDimSelection(references2d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs2d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 2d vertical dimension from selection"));
return;
}
//what 3d geometry configuration did we receive?
DimensionGeometryType geometryRefs3d;
if (geometryRefs2d == TechDraw::isViewReference &&
!references3d.empty()) {
geometryRefs3d = validateDimSelection3d(partFeat,
references3d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs3d == TechDraw::isVertical) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 3d vertical dimension from selection"));
return;
}
}
//build the dimension
DrawViewDimension* dim = dimensionMaker(partFeat,
"DistanceY",
references2d,
references3d);
//position the Dimension text on the view
positionDimText(dim);
//Horrible hack to force Tree update (claimChildren)
double x = partFeat->X.getValue();
partFeat->X.setValue(x);
}
//===========================================================================
// TechDraw_AngularGroup
//===========================================================================
DEF_STD_CMD_ACL(CmdTechDrawAngularGroup)
CmdTechDrawAngularGroup::CmdTechDrawAngularGroup()
: Command("TechDraw_AngularGroup")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Angular Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_AngularGroup";
sStatusTip = sToolTipText;
}
void CmdTechDrawAngularGroup::activated(int iMsg)
{
// Base::Console().Message("CMD::LinearGrp - activated(%d)\n", iMsg);
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
if (dlg) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"),
QObject::tr("Close active task dialog and try again."));
return;
}
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
pcAction->setIcon(pcAction->actions().at(iMsg)->icon());
switch(iMsg) {
case 0:
execAngle(this);
break;
case 1:
execAngle3Pt(this);
break;
default:
Base::Console().Message("CMD::AngularGrp - invalid iMsg: %d\n", iMsg);
};
}
Gui::Action * CmdTechDrawAngularGroup::createAction()
{
Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow());
pcAction->setDropDownMenu(true);
applyCommandData(this->className(), pcAction);
QAction* p0 = pcAction->addAction(QString());
p0->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_AngleDimension"));
p0->setObjectName(QString::fromLatin1("TechDraw_AngleDimension"));
p0->setWhatsThis(QString::fromLatin1("TechDraw_AngleDimension"));
QAction* p1 = pcAction->addAction(QString());
p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_3PtAngleDimension"));
p1->setObjectName(QString::fromLatin1("TechDraw_3PtAngleDimension"));
p1->setWhatsThis(QString::fromLatin1("TechDraw_3PtAngleDimension"));
_pcAction = pcAction;
languageChange();
pcAction->setIcon(p0->icon());
int defaultId = 0;
pcAction->setProperty("defaultAction", QVariant(defaultId));
return pcAction;
}
void CmdTechDrawAngularGroup::languageChange()
{
Command::languageChange();
if (!_pcAction)
return;
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
QAction* arc0 = a[0];
arc0->setText(QApplication::translate("CmdTechDrawAngularGroup", "Angular Dimension"));
arc0->setToolTip(QApplication::translate("TechDraw_AngleDimension", "Insert Angle Dimension"));
arc0->setStatusTip(arc0->toolTip()); QAction* arc1 = a[1];
arc1->setText(QApplication::translate("CmdTechDrawAngularGroup", "3Pt Angular Dimension"));
arc1->setToolTip(QApplication::translate("TechDraw_3PtAngleDimension", "Insert 3-Point Angle Dimension"));
arc1->setStatusTip(arc1->toolTip());
}
bool CmdTechDrawAngularGroup::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, false);
return (havePage && haveView);
}
//===========================================================================
// TechDraw_AngleDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawAngleDimension)
CmdTechDrawAngleDimension::CmdTechDrawAngleDimension()
: Command("TechDraw_AngleDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Angle Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_AngleDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_AngleDimension";
}
void CmdTechDrawAngleDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
execAngle(this);
}
bool CmdTechDrawAngleDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
void execAngle(Gui::Command* cmd)
{
bool result = _checkDrawViewPart(cmd);
if (!result) {
QMessageBox::warning( Gui::getMainWindow(),
QObject::tr("Incorrect selection"),
QObject::tr("No View of a Part in selection.") );
return;
}
ReferenceVector references2d;
ReferenceVector references3d;
TechDraw::DrawViewPart* partFeat = TechDraw::getReferencesFromSelection(references2d, references3d);
//Define the geometric configuration required for a length dimension
StringVector acceptableGeometry( { "Edge" } );
std::vector<int> minimumCounts( { 2 } );
std::vector<DimensionGeometryType> acceptableDimensionGeometrys( { isAngle } );
//what 2d geometry configuration did we receive?
DimensionGeometryType geometryRefs2d = validateDimSelection(references2d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs2d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 2d angle dimension from selection"));
return;
}
//what 3d geometry configuration did we receive?
DimensionGeometryType geometryRefs3d;
if (geometryRefs2d == TechDraw::isViewReference &&
!references3d.empty()) {
geometryRefs3d = validateDimSelection3d(partFeat,
references3d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs3d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 3d angle dimension from selection"));
return;
}
}
//build the dimension
DrawViewDimension* dim = dimensionMaker(partFeat,
"Angle",
references2d,
references3d);
//position the Dimension text on the view
positionDimText(dim);
//Horrible hack to force Tree update (claimChildren)
double x = partFeat->X.getValue();
partFeat->X.setValue(x);
}
//===========================================================================
// TechDraw_3PtAngleDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDraw3PtAngleDimension)
CmdTechDraw3PtAngleDimension::CmdTechDraw3PtAngleDimension()
: Command("TechDraw_3PtAngleDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert 3-Point Angle Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_3PtAngleDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_3PtAngleDimension";
}
void CmdTechDraw3PtAngleDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
execAngle3Pt(this);
}
bool CmdTechDraw3PtAngleDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
void execAngle3Pt(Gui::Command* cmd)
{
bool result = _checkDrawViewPart(cmd);
if (!result) {
QMessageBox::warning( Gui::getMainWindow(),
QObject::tr("Incorrect selection"),
QObject::tr("No View of a Part in selection.") );
return;
}
ReferenceVector references2d;
ReferenceVector references3d;
TechDraw::DrawViewPart* partFeat = TechDraw::getReferencesFromSelection(references2d, references3d);
//Define the geometric configuration required for a length dimension
StringVector acceptableGeometry( { "Vertex" } );
std::vector<int> minimumCounts( { 3 } );
std::vector<DimensionGeometryType> acceptableDimensionGeometrys( { isAngle3Pt } );
//what 2d geometry configuration did we receive?
DimensionGeometryType geometryRefs2d = validateDimSelection(references2d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs2d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 2d angle dimension from selection"));
return;
}
//what 3d geometry configuration did we receive?
DimensionGeometryType geometryRefs3d;
if (geometryRefs2d == TechDraw::isViewReference &&
!references3d.empty()) {
geometryRefs3d = validateDimSelection3d(partFeat,
references3d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs3d == TechDraw::isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 3d angle dimension from selection"));
return;
}
}
//build the dimension
DrawViewDimension* dim = dimensionMaker(partFeat,
"Angle3Pt",
references2d,
references3d);
//position the Dimension text on the view
positionDimText(dim);
//Horrible hack to force Tree update (claimChildren)
double x = partFeat->X.getValue();
partFeat->X.setValue(x);
}
//! link 3D geometry to Dimension(s) on a Page
//TODO: should we present all potential Dimensions from all Pages?
//===========================================================================
// TechDraw_LinkDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawLinkDimension)
CmdTechDrawLinkDimension::CmdTechDrawLinkDimension()
: Command("TechDraw_LinkDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Link Dimension to 3D Geometry");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_LinkDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_LinkDimension";
}
void CmdTechDrawLinkDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
TechDraw::DrawPage* page = DrawGuiUtil::findPage(this);
if (!page) {
return;
}
bool result = _checkSelection(this, 2);
if (!result)
return;
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx(nullptr,
App::DocumentObject::getClassTypeId(), Gui::ResolveMode::NoResolve);
App::DocumentObject* obj3D = nullptr;
std::vector<App::DocumentObject*> parts;
std::vector<std::string> subs;
std::vector<Gui::SelectionObject>::iterator itSel = selection.begin();
for (; itSel != selection.end(); itSel++) {
obj3D = ((*itSel).getObject());
std::vector<std::string> subList = (*itSel).getSubNames();
for (auto& s:subList) {
parts.push_back(obj3D);
subs.push_back(s);
}
}
if (!obj3D) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
QObject::tr("There is no 3D object in your selection"));
return;
}
if (subs.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
QObject::tr("There are no 3D Edges or Vertices in your selection"));
return;
}
// dialog to select the Dimension to link
Gui::Control().showDialog(new TaskDlgLinkDim(parts, subs, page));
page->getDocument()->recompute(); //still need to recompute in Gui. why?
}
bool CmdTechDrawLinkDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
bool taskInProgress = false;
if (havePage) {
taskInProgress = Gui::Control().activeDialog();
}
return (havePage && haveView && !taskInProgress);
}
//===========================================================================
// TechDraw_ExtentGroup
//===========================================================================
DEF_STD_CMD_ACL(CmdTechDrawExtentGroup)
CmdTechDrawExtentGroup::CmdTechDrawExtentGroup()
: Command("TechDraw_ExtentGroup")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Extent Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_ExtentGroup";
sStatusTip = sToolTipText;
// eType = ForEdit;
}
void CmdTechDrawExtentGroup::activated(int iMsg)
{
// Base::Console().Message("CMD::ExtentGrp - activated(%d)\n", iMsg);
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
if (dlg) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"),
QObject::tr("Close active task dialog and try again."));
return;
}
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
pcAction->setIcon(pcAction->actions().at(iMsg)->icon());
switch(iMsg) {
case 0:
execExtent(this, 0);
break;
case 1:
execExtent(this, 1);
break;
default:
Base::Console().Message("CMD::ExtGrp - invalid iMsg: %d\n", iMsg);
};
}
Gui::Action * CmdTechDrawExtentGroup::createAction()
{
Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow());
pcAction->setDropDownMenu(true);
applyCommandData(this->className(), pcAction);
QAction* p1 = pcAction->addAction(QString());
p1->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_HorizontalExtentDimension"));
p1->setObjectName(QString::fromLatin1("TechDraw_HorizontalExtentDimension"));
p1->setWhatsThis(QString::fromLatin1("TechDraw_HorizontalExtentDimension"));
QAction* p2 = pcAction->addAction(QString());
p2->setIcon(Gui::BitmapFactory().iconFromTheme("TechDraw_VerticalExtentDimension"));
p2->setObjectName(QString::fromLatin1("TechDraw_VerticalExtentDimension"));
p2->setWhatsThis(QString::fromLatin1("TechDraw_VerticalExtentDimension"));
_pcAction = pcAction;
languageChange();
pcAction->setIcon(p1->icon());
int defaultId = 0;
pcAction->setProperty("defaultAction", QVariant(defaultId));
return pcAction;
}
void CmdTechDrawExtentGroup::languageChange()
{
Command::languageChange();
if (!_pcAction)
return;
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
QAction* arc1 = a[0];
arc1->setText(QApplication::translate("CmdTechDrawExtentGroup", "Horizontal Extent"));
arc1->setToolTip(QApplication::translate("TechDraw_HorizontalExtent", "Insert Horizontal Extent Dimension"));
arc1->setStatusTip(arc1->toolTip());
QAction* arc2 = a[1];
arc2->setText(QApplication::translate("CmdTechDrawExtentGroup", "Vertical Extent"));
arc2->setToolTip(QApplication::translate("TechDraw_VerticalExtentDimension", "Insert Vertical Extent Dimension"));
arc2->setStatusTip(arc2->toolTip());
}
bool CmdTechDrawExtentGroup::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, false);
return (havePage && haveView);
}
//===========================================================================
// TechDraw_HorizontalExtentDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawHorizontalExtentDimension)
CmdTechDrawHorizontalExtentDimension::CmdTechDrawHorizontalExtentDimension()
: Command("TechDraw_HorizontalExtentDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Horizontal Extent Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_HorizontalExtentDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_HorizontalExtentDimension";
}
void CmdTechDrawHorizontalExtentDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
if (dlg) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"),
QObject::tr("Close active task dialog and try again."));
return;
}
execExtent(this, 0);
}
bool CmdTechDrawHorizontalExtentDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, false);
return (havePage && haveView);
}
void execExtent(Gui::Command* cmd, int direction)
{
bool result = _checkDrawViewPart(cmd);
if (!result) {
QMessageBox::warning( Gui::getMainWindow(),
QObject::tr("Incorrect selection"),
QObject::tr("No View of a Part in selection.") );
return;
}
ReferenceVector references2d;
ReferenceVector references3d;
TechDraw::DrawViewPart* partFeat = TechDraw::getReferencesFromSelection(references2d, references3d);
//Define the geometric configuration required for a extent dimension
StringVector acceptableGeometry( { "Edge" } );
std::vector<int> minimumCounts( { 1 } );
std::vector<DimensionGeometryType> acceptableDimensionGeometrys( { isMultiEdge,
isHorizontal,
isVertical,
isDiagonal,
isCircle,
isEllipse,
isBSplineCircle,
isBSpline,
isZLimited } );
//what 2d geometry configuration did we receive?
DimensionGeometryType geometryRefs2d = validateDimSelection(references2d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs2d == TechDraw::isInvalid) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 2d extent dimension from selection"));
return;
}
//what 3d geometry configuration did we receive?
DimensionGeometryType geometryRefs3d;
if (geometryRefs2d == TechDraw::isViewReference &&
!references3d.empty()) {
geometryRefs3d = validateDimSelection3d(partFeat,
references3d,
acceptableGeometry,
minimumCounts,
acceptableDimensionGeometrys);
if ( geometryRefs3d == isInvalid ) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Incorrect Selection"),
QObject::tr("Can not make 3d extent dimension from selection"));
return;
}
}
if (references3d.empty()) {
std::vector<std::string> edgeNames;
for (auto& ref : references2d) {
if (ref.getSubName().empty()) {
continue;
}
std::string geomType = DrawUtil::getGeomTypeFromName(ref.getSubName());
if (geomType == "Edge") {
edgeNames.push_back(ref.getSubName());
}
}
DrawDimHelper::makeExtentDim(partFeat,
edgeNames,
direction); //0 - horizontal, 1 - vertical
} else {
DrawDimHelper::makeExtentDim3d(partFeat,
references3d,
direction); //0 - horizontal, 1 - vertical
}
}
//===========================================================================
// TechDraw_VerticalExtentDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawVerticalExtentDimension)
CmdTechDrawVerticalExtentDimension::CmdTechDrawVerticalExtentDimension()
: Command("TechDraw_VerticalExtentDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Vertical Extent Dimension");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_VerticalExtentDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_VerticalExtentDimension";
}
void CmdTechDrawVerticalExtentDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
if (dlg) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Task In Progress"),
QObject::tr("Close active task dialog and try again."));
return;
}
execExtent(this, 1);
}
bool CmdTechDrawVerticalExtentDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, false);
return (havePage && haveView);
}
//===========================================================================
// TechDraw_DimensionRepair
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawDimensionRepair)
CmdTechDrawDimensionRepair::CmdTechDrawDimensionRepair()
: Command("TechDraw_DimensionRepair")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Repair Dimension References");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_DimensionRepair";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_DimensionRepair";
}
void CmdTechDrawDimensionRepair::activated(int iMsg)
{
Q_UNUSED(iMsg);
std::vector<App::DocumentObject*> dimObjs = getSelection().getObjectsOfType(TechDraw::DrawViewDimension::getClassTypeId());
TechDraw::DrawViewDimension* dim = nullptr;
if (dimObjs.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"),
QObject::tr("There is no Dimension in your selection"));
return;
} else {
dim = static_cast<TechDraw::DrawViewDimension*>(dimObjs.at(0));
}
ReferenceVector references2d;
ReferenceVector references3d;
//TechDraw::DrawViewPart* partFeat =
TechDraw::getReferencesFromSelection(references2d, references3d);
Gui::Control().showDialog(new TaskDlgDimReference(dim, references2d, references3d));
}
bool CmdTechDrawDimensionRepair::isActive(void)
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
bool taskInProgress = false;
if (havePage) {
taskInProgress = Gui::Control().activeDialog();
}
return (havePage && haveView && !taskInProgress);
}
//NOTE: to be deprecated. revisions to the basic dimension allows it to handle
//everything that the Landmark Dimension was created to handle.
//===========================================================================
// TechDraw_LandmarkDimension
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawLandmarkDimension)
CmdTechDrawLandmarkDimension::CmdTechDrawLandmarkDimension()
: Command("TechDraw_LandmarkDimension")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert Landmark Dimension - EXPERIMENTAL");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_LandmarkDimension";
sStatusTip = sToolTipText;
sPixmap = "TechDraw_LandmarkDimension";
}
void CmdTechDrawLandmarkDimension::activated(int iMsg)
{
Q_UNUSED(iMsg);
bool result = _checkSelection(this, 3);
if (!result)
return;
const std::vector<App::DocumentObject*> objects = getSelection().
getObjectsOfType(Part::Feature::getClassTypeId()); //??
if (objects.size() != 2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select 2 point objects and 1 View. (1)"));
return;
}
const std::vector<App::DocumentObject*> views = getSelection().
getObjectsOfType(TechDraw::DrawViewPart::getClassTypeId());
if (views.size() != 1) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select 2 point objects and 1 View. (2)"));
return;
}
TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(views.front());
std::vector<App::DocumentObject*> refs2d;
std::vector<std::string> subs;
subs.emplace_back("Vertex1");
subs.emplace_back("Vertex1");
TechDraw::DrawPage* page = dvp->findParentPage();
std::string parentName = dvp->getNameInDocument();
std::string PageName = page->getNameInDocument();
TechDraw::LandmarkDimension *dim = nullptr;
std::string FeatName = getUniqueObjectName("LandmarkDim");
openCommand(QT_TRANSLATE_NOOP("Command", "Create Dimension"));
doCommand(Doc, "App.activeDocument().addObject('TechDraw::LandmarkDimension', '%s')", FeatName.c_str());
if (objects.size() == 2) {
//what about distanceX and distanceY??
doCommand(Doc, "App.activeDocument().%s.Type = '%s'", FeatName.c_str(), "Distance");
refs2d.push_back(dvp);
refs2d.push_back(dvp);
}
// } else if (objects.size() == 3) { //not implemented yet
// doCommand(Doc, "App.activeDocument().%s.Type = '%s'", FeatName.c_str(), "Angle3Pt");
// refs2d.push_back(dvp);
// refs2d.push_back(dvp);
// refs2d.push_back(dvp);
// //subs.push_back("Vertex1");
// //subs.push_back("Vertex1");
// //subs.push_back("Vertex1");
// }
dim = dynamic_cast<TechDraw::LandmarkDimension *>(getDocument()->getObject(FeatName.c_str()));
if (!dim) {
throw Base::TypeError("CmdTechDrawLandmarkDimension - dim not found\n");
}
dim->References2D.setValues(refs2d, subs);
dim->References3D.setValues(objects, subs);
doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
commitCommand();
dim->recomputeFeature();
//Horrible hack to force Tree update
double x = dvp->X.getValue();
dvp->X.setValue(x);
}
bool CmdTechDrawLandmarkDimension::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
//------------------------------------------------------------------------------
void CreateTechDrawCommandsDims()
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new CmdTechDrawRadialGroup());
rcCmdMgr.addCommand(new CmdTechDrawDimension());
rcCmdMgr.addCommand(new CmdTechDrawRadiusDimension());
rcCmdMgr.addCommand(new CmdTechDrawDiameterDimension());
rcCmdMgr.addCommand(new CmdTechDrawLinearGroup());
rcCmdMgr.addCommand(new CmdTechDrawLengthDimension());
rcCmdMgr.addCommand(new CmdTechDrawHorizontalDimension());
rcCmdMgr.addCommand(new CmdTechDrawVerticalDimension());
rcCmdMgr.addCommand(new CmdTechDrawAngularGroup());
rcCmdMgr.addCommand(new CmdTechDrawAngleDimension());
rcCmdMgr.addCommand(new CmdTechDraw3PtAngleDimension());
rcCmdMgr.addCommand(new CmdTechDrawExtentGroup());
rcCmdMgr.addCommand(new CmdTechDrawVerticalExtentDimension());
rcCmdMgr.addCommand(new CmdTechDrawHorizontalExtentDimension());
rcCmdMgr.addCommand(new CmdTechDrawLinkDimension());
rcCmdMgr.addCommand(new CmdTechDrawLandmarkDimension());
rcCmdMgr.addCommand(new CmdTechDrawDimensionRepair());
}
//------------------------------------------------------------------------------
//Common code to build a dimension feature
DrawViewDimension* dimensionMaker(TechDraw::DrawViewPart* dvp,
std::string dimType,
ReferenceVector references2d,
ReferenceVector references3d)
{
TechDraw::DrawPage* page = dvp->findParentPage();
std::string PageName = page->getNameInDocument();
TechDraw::DrawViewDimension *dim = nullptr;
std::string dimName = dvp->getDocument()->getUniqueObjectName("Dimension");
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Dimension"));
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('TechDraw::DrawViewDimension', '%s')", dimName.c_str());
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.Type = '%s'", dimName.c_str()
,dimType.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MeasureType = '%s'", dimName.c_str(),
"Projected");
dim = dynamic_cast<TechDraw::DrawViewDimension *>(dvp->getDocument()->getObject(dimName.c_str()));
if (!dim) {
throw Base::TypeError("CmdTechDrawNewDiameterDimension - dim not found\n");
}
//always have References2D, even if only for the parent DVP
dim->setReferences2d(references2d);
dim->setReferences3d(references3d);
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), dimName.c_str());
Gui::Command::commitCommand();
dim->recomputeFeature();
return dim;
}
//position the Dimension text on the view
void positionDimText(DrawViewDimension* dim)
{
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second())/2.0;
dim->X.setValue(mid.x);
double fontSize = Preferences::dimFontSizeMM();
dim->Y.setValue(-mid.y + 0.5 * fontSize);
}
//===========================================================================
// Selection Validation Helpers
//===========================================================================
//! common checks of Selection for Dimension commands
//non-empty selection, no more than maxObjs selected and at least 1 DrawingPage exists
bool _checkSelection(Gui::Command* cmd, unsigned maxObjs) {
std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx();
if (selection.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect selection"),
QObject::tr("Select an object first"));
return false;
}
const std::vector<std::string> SubNames = selection[0].getSubNames();
if (SubNames.size() > maxObjs){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect selection"),
QObject::tr("Too many objects selected"));
return false;
}
std::vector<App::DocumentObject*> pages = cmd->getDocument()->getObjectsOfType(TechDraw::DrawPage::getClassTypeId());
if (pages.empty()){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect selection"),
QObject::tr("Create a page first."));
return false;
}
return true;
}
bool _checkDrawViewPart(Gui::Command* cmd) {
std::vector<Gui::SelectionObject> selection = cmd->getSelection().getSelectionEx();
for (auto& sel : selection) {
auto dvp = dynamic_cast<TechDraw::DrawViewPart *>( sel.getObject() );
if( dvp ) {
return true;
}
}
return false;
}