Merge pull request #13525 from Ondsel-Development/td_dimension

TechDraw: Smart dimension tool
This commit is contained in:
WandererFan
2024-05-13 12:31:32 -04:00
committed by GitHub
44 changed files with 3614 additions and 780 deletions

View File

@@ -125,11 +125,11 @@ PyMOD_INIT_FUNC(TechDrawGui)
// instantiating the commands
CreateTechDrawCommands();
CreateTechDrawCommandsDims();
CreateTechDrawCommandsDecorate();
CreateTechDrawCommandsAnnotate();
CreateTechDrawCommandsExtensionDims();
CreateTechDrawCommandsExtensions();
CreateTechDrawCommandsDims();
CreateTechDrawCommandsStack();
TechDrawGui::Workbench::init();

View File

@@ -102,6 +102,7 @@ SET(TechDrawGui_SRCS
CommandDecorate.cpp
CommandAnnotate.cpp
CommandExtensionDims.cpp
CommandExtensionDims.h
CommandExtensionPack.cpp
CommandStack.cpp
DimensionValidators.cpp
@@ -223,6 +224,8 @@ SET(TechDrawGui_SRCS
TaskCosmeticCircle.cpp
TaskCosmeticCircle.h
TaskCosmeticCircle.ui
TechDrawHandler.cpp
TechDrawHandler.h
Widgets/CompassDialWidget.cpp
Widgets/CompassDialWidget.h
Widgets/CompassWidget.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,8 @@
# include <QApplication>
# include <QMessageBox>
# include <sstream>
# include <BRepGProp.hxx>
# include <GProp_GProps.hxx>
#endif
# include <App/Document.h>
@@ -52,6 +54,7 @@
#include "DrawGuiUtil.h"
#include "TaskCustomizeFormat.h"
#include "TaskSelectLineAttributes.h"
#include "CommandExtensionDims.h"
using namespace TechDrawGui;
@@ -78,7 +81,7 @@ namespace TechDrawGui {
std::vector<TechDraw::DrawViewDimension*>_getDimensions(std::vector<Gui::SelectionObject> selection, std::string needDimType);
std::vector<dimVertex> _getVertexInfo(TechDraw::DrawViewPart* objFeat,
std::vector<std::string> subNames);
TechDraw::DrawViewDimension* _createLinDimension(Gui::Command* cmd,
TechDraw::DrawViewDimension* _createLinDimension(
TechDraw::DrawViewPart* objFeat,
std::string startVertex,
std::string endVertex,
@@ -1280,7 +1283,7 @@ void execCreateHorizChainDimension(Gui::Command* cmd) {
float yMaster = 0.0;
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(cmd, objFeat, allVertexes[n].name, allVertexes[n + 1].name, "DistanceX");
dim = _createLinDimension(objFeat, allVertexes[n].name, allVertexes[n + 1].name, "DistanceX");
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
dim->X.setValue(mid.x);
@@ -1347,7 +1350,7 @@ void execCreateVertChainDimension(Gui::Command* cmd) {
double fontSize = Preferences::dimFontSizeMM();
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(cmd, objFeat, allVertexes[n].name, allVertexes[n + 1].name, "DistanceY");
dim = _createLinDimension(objFeat, allVertexes[n].name, allVertexes[n + 1].name, "DistanceY");
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
if (n == 0)
@@ -1404,7 +1407,37 @@ void execCreateObliqueChainDimension(Gui::Command* cmd) {
}
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Oblique Chain Dim"));
const std::vector<std::string> subNames = selection[0].getSubNames();
std::vector<TechDraw::ReferenceEntry> refs;
for (auto& subName : selection[0].getSubNames()) {
refs.push_back(ReferenceEntry(objFeat, subName));
}
auto dims = makeObliqueChainDimension(refs);
if(dims.empty()){
Gui::Command::abortCommand();
}
else {
objFeat->refreshCEGeoms();
objFeat->requestPaint();
cmd->getSelection().clearSelection();
Gui::Command::commitCommand();
}
}
std::vector<DrawViewDimension*> TechDrawGui::makeObliqueChainDimension(std::vector<TechDraw::ReferenceEntry> refs)
{
if (refs.empty()) {
return {};
}
std::vector<std::string> subNames;
auto* objFeat = static_cast<DrawViewPart*>(refs[0].getObject());
for (auto& ref : refs) {
subNames.push_back(ref.getSubName());
}
std::vector<DrawViewDimension*> dims;
std::vector<dimVertex> allVertexes, carrierVertexes;
allVertexes = _getVertexInfo(objFeat, subNames);
if (!allVertexes.empty() && allVertexes.size() > 1) {
@@ -1443,17 +1476,16 @@ void execCreateObliqueChainDimension(Gui::Command* cmd) {
double fontSize = Preferences::dimFontSizeMM();
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(cmd, objFeat, carrierVertexes[n].name, carrierVertexes[n + 1].name, "Distance");
dim = _createLinDimension(objFeat, carrierVertexes[n].name, carrierVertexes[n + 1].name, "Distance");
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0 + delta;
dim->X.setValue(mid.x);
dim->Y.setValue(-mid.y + 0.5 * fontSize);
dims.push_back(dim);
}
objFeat->refreshCEGeoms();
objFeat->requestPaint();
cmd->getSelection().clearSelection();
Gui::Command::commitCommand();
}
return dims;
}
DEF_STD_CMD_A(CmdTechDrawExtensionCreateObliqueChainDimension)
@@ -1630,7 +1662,7 @@ void execCreateHorizCoordDimension(Gui::Command* cmd) {
dimDistance = -dimDistance;
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(cmd, objFeat, allVertexes[0].name, allVertexes[n + 1].name, "DistanceX");
dim = _createLinDimension(objFeat, allVertexes[0].name, allVertexes[n + 1].name, "DistanceX");
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
dim->X.setValue(mid.x);
@@ -1703,7 +1735,7 @@ void execCreateVertCoordDimension(Gui::Command* cmd) {
double fontSize = Preferences::dimFontSizeMM();
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(cmd, objFeat, allVertexes[0].name, allVertexes[n + 1].name, "DistanceY");
dim = _createLinDimension(objFeat, allVertexes[0].name, allVertexes[n + 1].name, "DistanceY");
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
dim->X.setValue(xMaster + dimDistance * n);
@@ -1760,7 +1792,37 @@ void execCreateObliqueCoordDimension(Gui::Command* cmd) {
}
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Oblique Coord Dim"));
const std::vector<std::string> subNames = selection[0].getSubNames();
std::vector<TechDraw::ReferenceEntry> refs;
for (auto& subName : selection[0].getSubNames()) {
refs.push_back(ReferenceEntry(objFeat, subName));
}
auto dims = makeObliqueCoordDimension(refs);
if (dims.empty()) {
Gui::Command::abortCommand();
}
else {
objFeat->refreshCEGeoms();
objFeat->requestPaint();
cmd->getSelection().clearSelection();
Gui::Command::commitCommand();
}
}
std::vector<DrawViewDimension*> TechDrawGui::makeObliqueCoordDimension(std::vector<TechDraw::ReferenceEntry> refs)
{
if (refs.empty()) {
return {};
}
std::vector<std::string> subNames;
auto* objFeat = static_cast<DrawViewPart*>(refs[0].getObject());
for (auto& ref : refs) {
subNames.push_back(ref.getSubName());
}
std::vector<DrawViewDimension*> dims;
std::vector<dimVertex> allVertexes, carrierVertexes;
allVertexes = _getVertexInfo(objFeat, subNames);
if (!allVertexes.empty() && allVertexes.size() > 1) {
@@ -1804,17 +1866,16 @@ void execCreateObliqueCoordDimension(Gui::Command* cmd) {
double fontSize = Preferences::dimFontSizeMM();
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(cmd, objFeat, carrierVertexes[0].name, carrierVertexes[n + 1].name, "Distance");
dim = _createLinDimension(objFeat, carrierVertexes[0].name, carrierVertexes[n + 1].name, "Distance");
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0 + delta * (n + 1);
dim->X.setValue(mid.x);
dim->Y.setValue(-mid.y + 0.5 * fontSize);
dims.push_back(dim);
}
}
objFeat->refreshCEGeoms();
objFeat->requestPaint();
cmd->getSelection().clearSelection();
Gui::Command::commitCommand();
return dims;
}
DEF_STD_CMD_A(CmdTechDrawExtensionCreateObliqueCoordDimension)
@@ -1991,7 +2052,7 @@ void execCreateHorizChamferDimension(Gui::Command* cmd) {
if (!allVertexes.empty() && allVertexes.size() > 1) {
const auto Pi180 = 180.0 / M_PI;
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(cmd, objFeat, allVertexes[0].name, allVertexes[1].name, "DistanceX");
dim = _createLinDimension(objFeat, allVertexes[0].name, allVertexes[1].name, "DistanceX");
float yMax = std::max(abs(allVertexes[0].point.y), abs(allVertexes[1].point.y)) + 7.0;
if (std::signbit(allVertexes[0].point.y))
yMax = -yMax;
@@ -2060,7 +2121,7 @@ void execCreateVertChamferDimension(Gui::Command* cmd) {
if (!allVertexes.empty() && allVertexes.size() > 1) {
const auto Pi180 = 180.0 / M_PI;
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(cmd, objFeat, allVertexes[0].name, allVertexes[1].name, "DistanceY");
dim = _createLinDimension(objFeat, allVertexes[0].name, allVertexes[1].name, "DistanceY");
float xMax = std::max(abs(allVertexes[0].point.x), abs(allVertexes[1].point.x)) + 7.0;
if (std::signbit(allVertexes[0].point.x))
xMax = -xMax;
@@ -2240,47 +2301,19 @@ void CmdTechDrawExtensionCreateLengthArc::activated(int iMsg) {
}
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Arc Length Dim"));
const std::vector<std::string> subNames = selection[0].getSubNames();
int geoId = TechDraw::DrawUtil::getIndexFromName(subNames[0]);
TechDraw::BaseGeomPtr geom = objFeat->getGeomByIndex(geoId);
std::string geoType = TechDraw::DrawUtil::getGeomTypeFromName(subNames[0]);
if (geoType == "Edge" && geom->getGeomType() == TechDraw::ARCOFCIRCLE) {
TechDraw::AOCPtr arcTag = std::static_pointer_cast<TechDraw::AOC>(geom);
float radius = arcTag->radius;
Base::Vector3d centerPt = arcTag->center;
centerPt.y = -centerPt.y;
Base::Vector3d startPt = arcTag->startPnt;
startPt.y = -startPt.y;
Base::Vector3d endPt = arcTag->endPnt;
endPt.y = -endPt.y;
std::stringstream startName, endName, formatSpec;
double scale = objFeat->getScale();
Base::Vector3d cvPoint = CosmeticVertex::makeCanonicalPoint(objFeat, startPt);
std::string startVertTag = objFeat->addCosmeticVertex(cvPoint);
int startVertNumber = objFeat->add1CVToGV(startVertTag);
startName << "Vertex" << startVertNumber;
cvPoint = CosmeticVertex::makeCanonicalPoint(objFeat, endPt);
std::string endVertTag = objFeat->addCosmeticVertex(cvPoint);
int endVertNumber = objFeat->add1CVToGV(endVertTag);
endName << "Vertex" << endVertNumber;
TechDraw::DrawViewDimension* dim;
dim = _createLinDimension(this, objFeat, startName.str(), endName.str(), "Distance");
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
dim->X.setValue(mid.x);
dim->Y.setValue(-mid.y);
Base::Vector3d radVec1 = startPt - centerPt;
Base::Vector3d radVec2 = endPt - centerPt;
float alpha = acos((radVec1 * radVec2) / (radVec1.Length() * radVec2.Length()));
float arcLength = alpha * radius / scale;
dim->Arbitrary.setValue(true);
formatSpec << "" << arcLength;
dim->FormatSpec.setValue(formatSpec.str());
ReferenceEntry ref(objFeat, selection[0].getSubNames()[0]);
TechDraw::DrawViewDimension* dim = makeArcLengthDimension(ref);
if (dim) {
objFeat->refreshCEGeoms();
objFeat->requestPaint();
getSelection().clearSelection();
Gui::Command::commitCommand();
}
else {
Gui::Command::abortCommand();
}
Gui::Command::commitCommand();
}
bool CmdTechDrawExtensionCreateLengthArc::isActive()
@@ -2329,6 +2362,51 @@ bool CmdTechDrawExtensionCustomizeFormat::isActive()
return (havePage && haveView);
}
DrawViewDimension* TechDrawGui::makeArcLengthDimension(const ReferenceEntry& ref)
{
DrawViewDimension* dim = nullptr;
auto* dvp = static_cast<DrawViewPart*>(ref.getObject());
int geoId = DrawUtil::getIndexFromName(ref.getSubName());
BaseGeomPtr geom = dvp->getGeomByIndex(geoId);
// Find the edge length.
TechDraw::BaseGeomPtr edge = dvp->getEdge(ref.getSubName());
if (!edge) {
return nullptr;
}
GProp_GProps edgeProps;
BRepGProp::LinearProperties(edge->getOCCEdge(), edgeProps);
double length = edgeProps.Mass() / dvp->getScale();
Base::Vector3d startPt = edge->getStartPoint();
Base::Vector3d endPt = edge->getEndPoint();
startPt.y = -startPt.y;
endPt.y = -endPt.y;
std::stringstream startName, endName, formatSpec;
Base::Vector3d cvPoint = CosmeticVertex::makeCanonicalPoint(dvp, startPt);
std::string startVertTag = dvp->addCosmeticVertex(cvPoint);
int startVertNumber = dvp->add1CVToGV(startVertTag);
startName << "Vertex" << startVertNumber;
cvPoint = CosmeticVertex::makeCanonicalPoint(dvp, endPt);
std::string endVertTag = dvp->addCosmeticVertex(cvPoint);
int endVertNumber = dvp->add1CVToGV(endVertTag);
endName << "Vertex" << endVertNumber;
dim = _createLinDimension(dvp, startName.str(), endName.str(), "Distance");
TechDraw::pointPair pp = dim->getLinearPoints();
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
dim->X.setValue(mid.x);
dim->Y.setValue(-mid.y);
dim->Arbitrary.setValue(true);
formatSpec << "" << length;
dim->FormatSpec.setValue(formatSpec.str());
return dim;
}
namespace TechDrawGui {
//===========================================================================
// internal helper routines
@@ -2387,7 +2465,8 @@ namespace TechDrawGui {
}
return true;
}
TechDraw::DrawViewDimension* _createLinDimension(Gui::Command* cmd,
TechDraw::DrawViewDimension* _createLinDimension(
TechDraw::DrawViewPart* objFeat,
std::string startVertex,
std::string endVertex,
@@ -2396,21 +2475,21 @@ namespace TechDrawGui {
{
TechDraw::DrawPage* page = objFeat->findParentPage();
std::string PageName = page->getNameInDocument();
TechDraw::DrawViewDimension* dim = nullptr;
std::string FeatName = cmd->getUniqueObjectName("Dimension");
std::string FeatName = objFeat->getDocument()->getUniqueObjectName("Dimension");
std::vector<App::DocumentObject*> objs;
std::vector<std::string> subs;
objs.push_back(objFeat);
objs.push_back(objFeat);
subs.push_back(startVertex);
subs.push_back(endVertex);
cmd->doCommand(cmd->Doc, "App.activeDocument().addObject('TechDraw::DrawViewDimension', '%s')", FeatName.c_str());
cmd->doCommand(cmd->Doc, "App.activeDocument().%s.Type = '%s'", FeatName.c_str(), dimType.c_str());
dim = dynamic_cast<TechDraw::DrawViewDimension*>(cmd->getDocument()->getObject(FeatName.c_str()));
if (!dim)
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('TechDraw::DrawViewDimension', '%s')", FeatName.c_str());
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.Type = '%s'", FeatName.c_str(), dimType.c_str());
auto dim = dynamic_cast<TechDraw::DrawViewDimension*>(objFeat->getDocument()->getObject(FeatName.c_str()));
if (!dim){
throw Base::TypeError("CmdTechDrawExtensionCreateLinDimension - dim not found\n");
}
dim->References2D.setValues(objs, subs);
cmd->doCommand(cmd->Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
// Touch the parent feature so the dimension in tree view appears as a child
objFeat->touch();

View File

@@ -0,0 +1,41 @@
/***************************************************************************
* Copyright (c) 2021 edi *
* *
* 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 *
* *
***************************************************************************/
#ifndef TECHDRAWGUI_CommandExtensionDims_H
#define TECHDRAWGUI_CommandExtensionDims_H
#include <Mod/TechDraw/TechDrawGlobal.h>
namespace TechDraw
{
class ReferenceEntry;
class DrawViewDimension;
}
namespace TechDrawGui {
TechDraw::DrawViewDimension* makeArcLengthDimension(const TechDraw::ReferenceEntry& ref);
std::vector<TechDraw::DrawViewDimension*> makeObliqueChainDimension(std::vector<TechDraw::ReferenceEntry> refs);
std::vector<TechDraw::DrawViewDimension*> makeObliqueCoordDimension(std::vector<TechDraw::ReferenceEntry> refs);
}
#endif // TECHDRAWGUI_CommandExtensionDims_H

View File

@@ -116,7 +116,7 @@ DimensionGeometryType TechDraw::validateDimSelection(
StringVector subNames;
TechDraw::DrawViewPart* dvpSave(nullptr);
for (auto& ref : references) {
TechDraw::DrawViewPart* dvp = dynamic_cast<TechDraw::DrawViewPart*>(ref.getObject());
auto* dvp = dynamic_cast<TechDraw::DrawViewPart*>(ref.getObject());
if (dvp) {
dvpSave = dvp;
if (!ref.getSubName().empty()) {
@@ -295,6 +295,10 @@ DimensionGeometryType TechDraw::getGeometryConfiguration(ReferenceVector valid2d
if (config > isInvalid) {
return config;
}
config = isValidSingleFace(valid2dReferences.front());
if (config > isInvalid) {
return config;
}
// no valid configuration found
return isInvalid;
@@ -336,6 +340,10 @@ DimensionGeometryType TechDraw::getGeometryConfiguration3d(DrawViewPart* dvp,
if (config > isInvalid) {
return config;
}
config = isValidSingleFace3d(dvp, valid3dReferences.front());
if (config > isInvalid) {
return config;
}
config = isValidHybrid3d(dvp, valid3dReferences);
if (config > isInvalid) {
return config;
@@ -461,6 +469,47 @@ DimensionGeometryType TechDraw::isValidSingleEdge3d(DrawViewPart* dvp, Reference
return isInvalid;
}
//! verify that Selection contains a valid Geometry for a single Edge Dimension
DimensionGeometryType TechDraw::isValidSingleFace(ReferenceEntry ref)
{
auto objFeat(dynamic_cast<TechDraw::DrawViewPart*>(ref.getObject()));
if (!objFeat) {
return isInvalid;
}
//the Name starts with "Edge"
std::string geomName = DrawUtil::getGeomTypeFromName(ref.getSubName());
if (geomName != "Face") {
return isInvalid;
}
auto geom = objFeat->getFace(ref.getSubName());
if (!geom) {
return isInvalid;
}
return isFace;
}
//! verify that Selection contains a valid Geometry for a single Edge Dimension
DimensionGeometryType TechDraw::isValidSingleFace3d(DrawViewPart* dvp, ReferenceEntry ref)
{
(void)dvp;
//the Name starts with "Edge"
std::string geomName = DrawUtil::getGeomTypeFromName(ref.getSubName());
if (geomName != "Face") {
return isInvalid;
}
TopoDS_Shape refShape = ref.getGeometry();
if (refShape.IsNull() || refShape.ShapeType() != TopAbs_FACE) {
Base::Console().Warning("Geometry for reference is not a face.\n");
return isInvalid;
}
return isFace;
}
//! verify that the edge references can make a dimension. Currently only extent
//! dimensions support more than 2 edges
DimensionGeometryType TechDraw::isValidMultiEdge(ReferenceVector refs)

View File

@@ -60,6 +60,7 @@ enum DimensionGeometryEnum {
isMultiEdge,
isZLimited,
isHybrid,
isFace,
isViewReference //never needs to be specified in the acceptable list
};
@@ -89,11 +90,13 @@ bool checkGeometryOccurrences(StringVector subNames, GeomCountMap keyedMinimumCo
DimensionGeometryType isValidVertexes(ReferenceVector refs);
DimensionGeometryType isValidMultiEdge(ReferenceVector refs);
DimensionGeometryType isValidSingleEdge(ReferenceEntry ref);
DimensionGeometryType isValidSingleFace(ReferenceEntry ref);
DimensionGeometryType isValidHybrid(ReferenceVector refs);
DimensionGeometryType isValidVertexes3d(DrawViewPart* dvp, ReferenceVector refs);
DimensionGeometryType isValidMultiEdge3d(DrawViewPart* dvp, ReferenceVector refs);
DimensionGeometryType isValidSingleEdge3d(DrawViewPart* dvp, ReferenceEntry ref);
DimensionGeometryType isValidSingleFace3d(DrawViewPart* dvp, ReferenceEntry ref);
DimensionGeometryType isValidHybrid3d(DrawViewPart* dvp, ReferenceVector refs);
long int mapGeometryTypeToDimType(long int dimType, DimensionGeometryType geometry2d,

View File

@@ -524,9 +524,9 @@ Multiplier of 'Font Size'</string>
<item row="9" column="2">
<widget class="Gui::PrefDoubleSpinBox" name="pdsbGapISO">
<property name="toolTip">
<string>Controls the size of gap between dimension point and start of extension line for ISO dimensions.
Value * linewidth is the gap.
Normally, no gap is used. If using a gap, the recommended value 8.</string>
<string>Controls the size of gap between dimension point and start of extension line for ISO dimensions.
Value * linewidth is the gap.
Normally, no gap is used. If using a gap, the recommended value 8.</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -545,8 +545,8 @@ Normally, no gap is used. If using a gap, the recommended value 8.</string>
<item row="10" column="2">
<widget class="Gui::PrefDoubleSpinBox" name="pdsbGapASME">
<property name="toolTip">
<string>Controls the size of gap between dimension point and start of extension line for ASME dimensions. Value * linewidth is the gap.
Normally, no gap is used. If a gap is used, the recommended value is 6.</string>
<string>Controls the size of gap between dimension point and start of extension line for ASME dimensions. Value * linewidth is the gap.
Normally, no gap is used. If a gap is used, the recommended value is 6.</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -618,6 +618,56 @@ Normally, no gap is used. If a gap is used, the recommended value is 6.</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Tools</string>
</property>
<layout class="QGridLayout" name="gridLayout_general">
<item row="0" column="0">
<widget class="QLabel" name="dimensioningLabel">
<property name="text">
<string>Dimensioning tools:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="dimensioningMode">
<property name="toolTip">
<string>Select the type of dimensioning tools for your toolbar:
'Single tool': A single tool for all dimensioning in the toolbar: Distance, Distance X / Y, Angle, Radius. (Others in dropdown)
'Separated tools': Individual tools for each dimensioning tool.
'Both': You will have both the 'Dimension' tool and the separated tools.
This setting is only for the toolbar. Whichever you choose, all tools are always available in the menu and through shortcuts.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="radiusDiameterLabel">
<property name="text">
<string>Dimension tool diameter/radius mode:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="radiusDiameterMode">
<property name="toolTip">
<string>While using the Dimension tool you may choose how to handle circles and arcs:
'Auto': The tool will apply radius to arcs and diameter to circles.
'Diameter': The tool will apply diameter to all.
'Radius': The tool will apply radius to all.</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

View File

@@ -25,6 +25,7 @@
#include "PreCompiled.h"
#include <Base/Tools.h>
#include <App/Application.h>
#include "DlgPrefsTechDrawDimensionsImp.h"
#include "ui_DlgPrefsTechDrawDimensions.h"
@@ -67,6 +68,61 @@ void DlgPrefsTechDrawDimensionsImp::saveSettings()
ui->pdsbGapISO->onSave();
ui->pdsbGapASME->onSave();
ui->pdsbLineSpacingFactorISO->onSave();
enum
{
DimensionSingleTool,
DimensionSeparateTools,
DimensionBoth
};
// Dimensioning constraints mode
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/TechDraw/dimensioning");
bool singleTool = true;
bool SeparatedTools = false;
int index = ui->dimensioningMode->currentIndex();
switch (index) {
case DimensionSeparateTools:
singleTool = false;
SeparatedTools = true;
break;
case DimensionBoth:
singleTool = true;
SeparatedTools = true;
break;
}
hGrp->SetBool("SingleDimensioningTool", singleTool);
hGrp->SetBool("SeparatedDimensioningTools", SeparatedTools);
ui->radiusDiameterMode->setEnabled(index != 1);
enum
{
DimensionAutoRadiusDiam,
DimensionDiameter,
DimensionRadius
};
bool Diameter = true;
bool Radius = true;
index = ui->radiusDiameterMode->currentIndex();
switch (index) {
case DimensionDiameter:
Diameter = true;
Radius = false;
break;
case DimensionRadius:
Diameter = false;
Radius = true;
break;
}
hGrp->SetBool("DimensioningDiameter", Diameter);
hGrp->SetBool("DimensioningRadius", Radius);
if (property("dimensioningMode").toInt() != ui->dimensioningMode->currentIndex()) {
requireRestart();
}
}
void DlgPrefsTechDrawDimensionsImp::loadSettings()
@@ -101,6 +157,42 @@ void DlgPrefsTechDrawDimensionsImp::loadSettings()
ui->pdsbGapASME->onRestore();
ui->pdsbLineSpacingFactorISO->onRestore();
// Dimensioning constraints mode
ui->dimensioningMode->clear();
ui->dimensioningMode->addItem(tr("Single tool"));
ui->dimensioningMode->addItem(tr("Separated tools"));
ui->dimensioningMode->addItem(tr("Both"));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/TechDraw/dimensioning");
bool singleTool = hGrp->GetBool("SingleDimensioningTool", true);
bool SeparatedTools = hGrp->GetBool("SeparatedDimensioningTools", true);
int index = SeparatedTools ? (singleTool ? 2 : 1) : 0;
ui->dimensioningMode->setCurrentIndex(index);
setProperty("dimensioningMode", index);
connect(ui->dimensioningMode,
QOverload<int>::of(&QComboBox::currentIndexChanged),
this,
&DlgPrefsTechDrawDimensionsImp::dimensioningModeChanged);
ui->radiusDiameterMode->setEnabled(index != 1);
// Dimensioning constraints mode
ui->radiusDiameterMode->clear();
ui->radiusDiameterMode->addItem(tr("Auto"));
ui->radiusDiameterMode->addItem(tr("Diameter"));
ui->radiusDiameterMode->addItem(tr("Radius"));
bool Diameter = hGrp->GetBool("DimensioningDiameter", true);
bool Radius = hGrp->GetBool("DimensioningRadius", true);
index = Diameter ? (Radius ? 0 : 1) : 2;
ui->radiusDiameterMode->setCurrentIndex(index);
}
void DlgPrefsTechDrawDimensionsImp::dimensioningModeChanged(int index)
{
ui->radiusDiameterMode->setEnabled(index != 1);
}
/**

View File

@@ -45,6 +45,7 @@ protected:
void saveSettings() override;
void loadSettings() override;
void changeEvent(QEvent *e) override;
void dimensioningModeChanged(int index);
int prefArrowStyle() const;

View File

@@ -110,6 +110,7 @@ MDIViewPage::MDIViewPage(ViewProviderPage* pageVp, Gui::Document* doc, QWidget*
connect(m_printAllAction, &QAction::triggered, this, qOverload<>(&MDIViewPage::printAllPages));
isSelectionBlocked = false;
isContextualMenuEnabled = true;
QString tabText = QString::fromUtf8(pageVp->getDrawPage()->getNameInDocument());
tabText += QString::fromUtf8("[*]");
@@ -461,14 +462,16 @@ PyObject* MDIViewPage::getPyObject()
void MDIViewPage::contextMenuEvent(QContextMenuEvent* event)
{
// Base::Console().Message("MDIVP::contextMenuEvent() - reason: %d\n", event->reason());
QMenu menu;
menu.addAction(m_toggleFrameAction);
menu.addAction(m_toggleKeepUpdatedAction);
menu.addAction(m_exportSVGAction);
menu.addAction(m_exportDXFAction);
menu.addAction(m_exportPDFAction);
menu.addAction(m_printAllAction);
menu.exec(event->globalPos());
if (isContextualMenuEnabled) {
QMenu menu;
menu.addAction(m_toggleFrameAction);
menu.addAction(m_toggleKeepUpdatedAction);
menu.addAction(m_exportSVGAction);
menu.addAction(m_exportDXFAction);
menu.addAction(m_exportPDFAction);
menu.addAction(m_printAllAction);
menu.exec(event->globalPos());
}
}
void MDIViewPage::toggleFrame() { m_vpPage->toggleFrameState(); }
@@ -755,13 +758,27 @@ void MDIViewPage::sceneSelectionChanged()
std::vector<Gui::SelectionObject> treeSel = Gui::Selection().getSelectionEx();
QList<QGraphicsItem*> sceneSel = m_qgSceneSelected;
//check if really need to change selection
bool sameSel = compareSelections(treeSel, sceneSel);
if (sameSel) {
return;
bool saveBlock = blockSelection(true);// block selectionChanged signal from Tree/Observer
blockSceneSelection(true);
if (sceneSel.empty()) {
if (!treeSel.empty()) {
Gui::Selection().clearSelection();
}
}
else {
for (auto& sel : treeSel) {
removeSelFromTreeSel(sceneSel, sel);
}
for (auto* scene : sceneSel) {
addSceneToTreeSel(scene, treeSel);
}
}
setTreeToSceneSelect();
blockSceneSelection(false);
blockSelection(saveBlock);
}
//Note: Qt says: "no guarantee of selection order"!!!
@@ -771,149 +788,48 @@ void MDIViewPage::setTreeToSceneSelect()
bool saveBlock = blockSelection(true);// block selectionChanged signal from Tree/Observer
blockSceneSelection(true);
Gui::Selection().clearSelection();
QList<QGraphicsItem*> sceneSel = m_qgSceneSelected;
for (QList<QGraphicsItem*>::iterator it = sceneSel.begin(); it != sceneSel.end(); ++it) {
QGIView* itemView = dynamic_cast<QGIView*>(*it);
for (auto* scene : m_qgSceneSelected) {
auto* itemView = dynamic_cast<QGIView*>(scene);
if (!itemView) {
QGIEdge* edge = dynamic_cast<QGIEdge*>(*it);
if (edge) {
QGraphicsItem* parent = edge->parentItem();
if (!parent) {
continue;
}
QGIView* viewItem = dynamic_cast<QGIView*>(parent);
if (!viewItem) {
continue;
}
TechDraw::DrawView* viewObj = viewItem->getViewObject();
std::stringstream ss;
ss << "Edge" << edge->getProjIndex();
//bool accepted =
static_cast<void>(Gui::Selection().addSelection(viewObj->getDocument()->getName(),
viewObj->getNameInDocument(),
ss.str().c_str()));
showStatusMsg(viewObj->getDocument()->getName(), viewObj->getNameInDocument(),
ss.str().c_str());
auto* parent = dynamic_cast<QGIView*>(scene->parentItem());
if (!parent) {
return;
}
TechDraw::DrawView* viewObj = parent->getViewObject();
if (!viewObj) {
continue;
}
const char* doc_name = viewObj->getDocument()->getName();
const char* obj_name = viewObj->getNameInDocument();
QGIVertex* vert = dynamic_cast<QGIVertex*>(*it);
if (vert) {
QGraphicsItem* parent = vert->parentItem();
if (!parent) {
continue;
}
auto* edge = dynamic_cast<QGIEdge*>(scene);
auto* vert = dynamic_cast<QGIVertex*>(scene);
auto* face = dynamic_cast<QGIFace*>(scene);
if (edge || vert || face) {
const char* ssn = getSceneSubName(scene).c_str();
QGIView* viewItem = dynamic_cast<QGIView*>(parent);
if (!viewItem) {
continue;
}
TechDraw::DrawView* viewObj = viewItem->getViewObject();
std::stringstream ss;
ss << "Vertex" << vert->getProjIndex();
//bool accepted =
static_cast<void>(Gui::Selection().addSelection(viewObj->getDocument()->getName(),
viewObj->getNameInDocument(),
ss.str().c_str()));
showStatusMsg(viewObj->getDocument()->getName(), viewObj->getNameInDocument(),
ss.str().c_str());
continue;
Gui::Selection().addSelection(doc_name, obj_name, ssn);
showStatusMsg(doc_name, obj_name, ssn);
return;
}
QGIFace* face = dynamic_cast<QGIFace*>(*it);
if (face) {
QGraphicsItem* parent = face->parentItem();
if (!parent) {
continue;
}
QGIView* viewItem = dynamic_cast<QGIView*>(parent);
if (!viewItem) {
continue;
}
TechDraw::DrawView* viewObj = viewItem->getViewObject();
std::stringstream ss;
ss << "Face" << face->getProjIndex();
//bool accepted =
static_cast<void>(Gui::Selection().addSelection(viewObj->getDocument()->getName(),
viewObj->getNameInDocument(),
ss.str().c_str()));
showStatusMsg(viewObj->getDocument()->getName(), viewObj->getNameInDocument(),
ss.str().c_str());
continue;
}
QGIDatumLabel* dimLabel = dynamic_cast<QGIDatumLabel*>(*it);
if (dimLabel) {
QGraphicsItem* dimParent = dimLabel->QGraphicsItem::parentItem();
if (!dimParent) {
continue;
}
QGIView* dimItem = dynamic_cast<QGIView*>(dimParent);
if (!dimItem) {
continue;
}
TechDraw::DrawView* dimObj = dimItem->getViewObject();
if (!dimObj) {
continue;
}
const char* name = dimObj->getNameInDocument();
if (!name) {//can happen during undo/redo if Dim is selected???
else if (dynamic_cast<QGIDatumLabel*>(scene) || dynamic_cast<QGMText*>(scene)) {
if (!obj_name) {//can happen during undo/redo if Dim is selected???
//Base::Console().Log("INFO - MDIVP::sceneSelectionChanged - dimObj name is null!\n");
continue;
}
//bool accepted =
static_cast<void>(Gui::Selection().addSelection(dimObj->getDocument()->getName(),
dimObj->getNameInDocument()));
}
QGMText* mText = dynamic_cast<QGMText*>(*it);
if (mText) {
QGraphicsItem* textParent = mText->QGraphicsItem::parentItem();
if (!textParent) {
continue;
}
QGIView* parent = dynamic_cast<QGIView*>(textParent);
if (!parent) {
continue;
}
TechDraw::DrawView* parentFeat = parent->getViewObject();
if (!parentFeat) {
continue;
}
const char* name = parentFeat->getNameInDocument();
if (!name) {//can happen during undo/redo if Dim is selected???
continue;
}
//bool accepted =
static_cast<void>(Gui::Selection().addSelection(
parentFeat->getDocument()->getName(), parentFeat->getNameInDocument()));
Gui::Selection().addSelection(doc_name, obj_name);
}
}
else {
TechDraw::DrawView* viewObj = itemView->getViewObject();
if (viewObj && !viewObj->isRemoving()) {
std::string doc_name = viewObj->getDocument()->getName();
std::string obj_name = viewObj->getNameInDocument();
const char* doc_name = viewObj->getDocument()->getName();
const char* obj_name = viewObj->getNameInDocument();
Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str());
showStatusMsg(doc_name.c_str(), obj_name.c_str(), "");
Gui::Selection().addSelection(doc_name, obj_name);
showStatusMsg(doc_name, obj_name, "");
}
}
}
@@ -922,6 +838,138 @@ void MDIViewPage::setTreeToSceneSelect()
blockSelection(saveBlock);
}
std::string MDIViewPage::getSceneSubName(QGraphicsItem* scene)
{
auto* edge = dynamic_cast<QGIEdge*>(scene);
auto* vert = dynamic_cast<QGIVertex*>(scene);
auto* face = dynamic_cast<QGIFace*>(scene);
if (edge || vert || face) {
auto* viewItem = dynamic_cast<QGIView*>(scene->parentItem());
if (viewItem) {
TechDraw::DrawView* viewObj = viewItem->getViewObject();
std::stringstream ss;
if (edge) { ss << "Edge" << edge->getProjIndex(); }
else if (vert) { ss << "Vertex" << vert->getProjIndex(); }
else { ss << "Face" << face->getProjIndex(); }
return ss.str();
}
}
return "";
}
// adds scene to core selection if it's not in already.
void MDIViewPage::addSceneToTreeSel(QGraphicsItem* sn, std::vector<Gui::SelectionObject> treeSel)
{
auto* itemView = dynamic_cast<QGIView*>(sn);
if (!itemView) {
auto* parent = dynamic_cast<QGIView*>(sn->parentItem());
if (!parent) {
return;
}
TechDraw::DrawView* viewObj = parent->getViewObject();
if (!viewObj) {
return;
}
const char* doc_name = viewObj->getDocument()->getName();
const char* obj_name = viewObj->getNameInDocument();
std::string sub_name;
if (dynamic_cast<QGIEdge*>(sn) || dynamic_cast<QGIVertex*>(sn) || dynamic_cast<QGIFace*>(sn)) {
sub_name = getSceneSubName(sn);
}
else if (dynamic_cast<QGIDatumLabel*>(sn) || dynamic_cast<QGMText*>(sn)) {
if (!obj_name) {//can happen during undo/redo if Dim is selected???
return;
}
}
else { // are there other cases?
return;
}
if (!Gui::Selection().isSelected(viewObj, sub_name.c_str())) {
Gui::Selection().addSelection(doc_name, obj_name, sub_name.c_str());
showStatusMsg(doc_name, obj_name, sub_name.c_str());
}
}
else {
TechDraw::DrawView* viewObj = itemView->getViewObject();
if (viewObj && !viewObj->isRemoving()) {
const char* doc_name = viewObj->getDocument()->getName();
const char* obj_name = viewObj->getNameInDocument();
if (!Gui::Selection().isSelected(viewObj)) {
Gui::Selection().addSelection(doc_name, obj_name);
showStatusMsg(doc_name, obj_name, "");
}
}
}
}
// remove core selection if scene is not selected anymore
void MDIViewPage::removeSelFromTreeSel(QList<QGraphicsItem*> sceneSel, Gui::SelectionObject& sel)
{
std::string selDocName = sel.getDocName();
App::DocumentObject* selObj = sel.getObject();
for (auto& sub : sel.getSubNames()) {
bool found = false;
for (auto& sn : sceneSel) {
auto* itemView = dynamic_cast<QGIView*>(sn);
if (!itemView) {
auto* parent = dynamic_cast<QGIView*>(sn->parentItem());
if (!parent) {
continue;
}
TechDraw::DrawView* viewObj = parent->getViewObject();
if (!viewObj) {
continue;
}
const char* doc_name = viewObj->getDocument()->getName();
const char* obj_name = viewObj->getNameInDocument();
std::string sub_name;
if (dynamic_cast<QGIEdge*>(sn) || dynamic_cast<QGIVertex*>(sn) || dynamic_cast<QGIFace*>(sn)) {
sub_name = getSceneSubName(sn);
}
else if (dynamic_cast<QGIDatumLabel*>(sn) || dynamic_cast<QGMText*>(sn)) {
if (!obj_name) {//can happen during undo/redo if Dim is selected???
continue;
}
}
else { // are there other cases?
continue;
}
if (selDocName == doc_name && selObj == viewObj && sub == sub_name) {
found = true;
break;
}
}
else {
TechDraw::DrawView* viewObj = itemView->getViewObject();
if (viewObj && !viewObj->isRemoving()) {
const char* doc_name = viewObj->getDocument()->getName();
const char* obj_name = viewObj->getNameInDocument();
if (selDocName == doc_name && selObj == viewObj) {
found = true;
break;
}
}
}
}
if (!found) {
Gui::Selection().rmvSelection(sel.getDocName(), sel.getObject()->getNameInDocument(), sub.c_str());
}
}
}
bool MDIViewPage::compareSelections(std::vector<Gui::SelectionObject> treeSel,
QList<QGraphicsItem*> sceneSel)
{
@@ -1020,6 +1068,17 @@ void MDIViewPage::showStatusMsg(const char* string1, const char* string2, const
}
}
void MDIViewPage::setDimensionsSelectability(bool val)
{
for (auto scene : m_scene->items()) {
auto* dl = dynamic_cast<QGIDatumLabel*>(scene);
if (dl) {
dl->setSelectability(val);
}
}
}
// ----------------------------------------------------------------------------
void MDIViewPagePy::init_type()

View File

@@ -109,6 +109,9 @@ public:
void setScene(QGSPage* scene, QGVPage* view);
void fixSceneDependencies();
void setDimensionsSelectability(bool val);
void enableContextualMenu(bool val) { isContextualMenuEnabled = val; }
public Q_SLOTS:
void viewAll() override;
void saveSVG();
@@ -127,6 +130,9 @@ protected:
void onDeleteObject(const App::DocumentObject& obj);
bool compareSelections(std::vector<Gui::SelectionObject> treeSel, QList<QGraphicsItem*> sceneSel);
void addSceneToTreeSel(QGraphicsItem* scene, std::vector<Gui::SelectionObject> treeSel);
void removeSelFromTreeSel(QList<QGraphicsItem*> sceneSel, Gui::SelectionObject& sel);
std::string getSceneSubName(QGraphicsItem* scene);
void setTreeToSceneSelect();
void sceneSelectionManager();
@@ -144,6 +150,7 @@ private:
std::string m_objectName;
std::string m_documentName;
bool isSelectionBlocked;
bool isContextualMenuEnabled;
QPointer<QGSPage> m_scene;
QString m_currentPath;

View File

@@ -33,6 +33,7 @@
#include <App/Material.h>
#include <Base/Console.h>
#include <Base/Parameter.h>
#include <Gui/Selection.h>
#include <Mod/TechDraw/App/Preferences.h>
#include <Mod/TechDraw/App/LineGenerator.h>
@@ -214,7 +215,8 @@ bool PreferencesGui::showGrid()
bool PreferencesGui::multiSelection()
{
return Preferences::getPreferenceGroup("General")->GetBool("multiSelection", false);
bool greedy = Gui::Selection().getSelectionStyle() == Gui::SelectionSingleton::SelectionStyle::GreedySelection;
return greedy || Preferences::getPreferenceGroup("General")->GetBool("multiSelection", false);
}
App::Color PreferencesGui::pageColor()

View File

@@ -93,8 +93,7 @@ QGIDatumLabel::QGIDatumLabel() : m_dragState(NoDrag)
setCacheMode(QGraphicsItem::NoCache);
setFlag(ItemSendsGeometryChanges, true);
setFlag(ItemIsMovable, true);
setFlag(ItemIsSelectable, true);
setAcceptHoverEvents(true);
setSelectability(true);
setFiltersChildEvents(true);
m_dimText = new QGCustomText();
@@ -445,6 +444,13 @@ void QGIDatumLabel::setColor(QColor color)
m_unitText->setColor(m_colNormal);
}
void QGIDatumLabel::setSelectability(bool val)
{
setFlag(ItemIsSelectable, val);
setAcceptHoverEvents(val);
setAcceptedMouseButtons(val ? Qt::AllButtons : Qt::NoButton);
}
//**************************************************************
QGIViewDimension::QGIViewDimension() : dvDimension(nullptr), hasHover(false), m_lineWidth(0.0)
{
@@ -717,9 +723,9 @@ void QGIViewDimension::draw()
return;
}
TechDraw::DrawViewDimension* dim = dynamic_cast<TechDraw::DrawViewDimension*>(getViewObject());
auto* dim = dynamic_cast<TechDraw::DrawViewDimension*>(getViewObject());
if (!dim ||//nothing to draw, don't try
!dim->isDerivedFrom(TechDraw::DrawViewDimension::getClassTypeId())
!dim->isDerivedFrom<TechDraw::DrawViewDimension>()
|| !dim->has2DReferences()) {
datumLabel->hide();
hide();
@@ -767,6 +773,9 @@ void QGIViewDimension::draw()
else if (strcmp(dimType, "Angle") == 0 || strcmp(dimType, "Angle3Pt") == 0) {
drawAngle(dim, vp);
}
else if (strcmp(dimType, "Area") == 0) {
drawArea(dim, vp);
}
else {
Base::Console().Error("QGIVD::draw - this DimensionType is unknown: %s\n", dimType);
}
@@ -1255,7 +1264,7 @@ void QGIViewDimension::resetArrows() const
}
void QGIViewDimension::drawArrows(int count, const Base::Vector2d positions[], double angles[],
bool flipped) const
bool flipped, bool forcePoint) const
{
const int arrowCount = 2;
QGIArrow* arrows[arrowCount] = {aHead1, aHead2};
@@ -1275,7 +1284,8 @@ void QGIViewDimension::drawArrows(int count, const Base::Vector2d positions[], d
continue;
}
arrow->setStyle(QGIArrow::getPrefArrowStyle());
// some dimensions must use point ends (area). The point style is 3.
arrow->setStyle(forcePoint ? 3 : QGIArrow::getPrefArrowStyle());
auto vp = static_cast<ViewProviderDimension*>(getViewProvider(getViewObject()));
auto arrowSize = vp->Arrowsize.getValue();
arrow->setSize(arrowSize);
@@ -1403,7 +1413,7 @@ void QGIViewDimension::drawDimensionLine(QPainterPath& painterPath,
const Base::Vector2d& targetPoint, double lineAngle,
double startPosition, double jointPosition,
const Base::BoundBox2d& labelRectangle, int arrowCount,
int standardStyle, bool flipArrows) const
int standardStyle, bool flipArrows, bool forcePointStyle) const
{
// Keep the convention start position <= 0
jointPosition *= normalizeStartPosition(startPosition, lineAngle);
@@ -1423,7 +1433,7 @@ void QGIViewDimension::drawDimensionLine(QPainterPath& painterPath,
arrowAngles[0] = lineAngle;
arrowAngles[1] = lineAngle + M_PI;
drawArrows(arrowCount, arrowPositions, arrowAngles, flipArrows);
drawArrows(arrowCount, arrowPositions, arrowAngles, flipArrows, forcePointStyle);
}
void QGIViewDimension::drawDimensionArc(QPainterPath& painterPath, const Base::Vector2d& arcCenter,
@@ -2085,6 +2095,75 @@ void QGIViewDimension::drawRadiusExecutive(const Base::Vector2d& centerPoint,
dimLines->setPath(radiusPath);
}
void QGIViewDimension::drawAreaExecutive(const Base::Vector2d& centerPoint, double area,
const Base::BoundBox2d& labelRectangle,
double centerOverhang, int standardStyle,
int renderExtent, bool flipArrow) const
{
QPainterPath areaPath;
Base::Vector2d labelCenter(labelRectangle.GetCenter());
double labelAngle = 0.0;
bool forcePointStyle = true;
if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING
|| standardStyle == ViewProviderDimension::STD_STYLE_ASME_REFERENCING) {
// The dimensional value text must stay horizontal
bool left = labelCenter.x < centerPoint.x;
Base::Vector2d jointDirection;
if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING) {
jointDirection = getIsoRefJointPoint(labelRectangle, left) - centerPoint;
}
else {
jointDirection = getAsmeRefJointPoint(labelRectangle, left) - centerPoint;
}
double lineAngle = jointDirection.Angle();
double jointPositions = jointDirection.Length();
drawDimensionLine(areaPath, centerPoint, lineAngle, 0.0, jointPositions, labelRectangle, 1, standardStyle, flipArrow, forcePointStyle);
Base::Vector2d outsetPoint(standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING
? getIsoRefOutsetPoint(labelRectangle, left)
: getAsmeRefOutsetPoint(labelRectangle, left));
areaPath.moveTo(toQtGui(outsetPoint));
areaPath.lineTo(toQtGui(centerPoint + jointDirection));
}
else if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_ORIENTED) {
// We may rotate the label so no reference line is needed
double lineAngle;
double devAngle = computeLineAndLabelAngles(centerPoint, labelCenter,
labelRectangle.Height() * 0.5 + getIsoDimensionLineSpacing(),
lineAngle, labelAngle);
lineAngle = lineAngle - M_PI;
double labelPosition = -cos(devAngle) * ((labelCenter - centerPoint).Length());
drawDimensionLine(areaPath, centerPoint, lineAngle, 0.0, labelPosition, labelRectangle, 1, standardStyle, flipArrow, forcePointStyle);
}
else if (standardStyle == ViewProviderDimension::STD_STYLE_ASME_INLINED) {
// Text must remain horizontal, but it may split the leader line
Base::Vector2d labelDirection(labelCenter - centerPoint);
double lineAngle = labelDirection.Angle();
double labelPosition = labelDirection.Length();
drawDimensionLine(areaPath, centerPoint, lineAngle, 0.0, labelPosition, labelRectangle, 1, standardStyle, flipArrow, forcePointStyle);
}
else {
Base::Console().Error(
"QGIVD::drawRadiusExecutive - this Standard&Style is not supported: %d\n",
standardStyle);
}
datumLabel->setTransformOriginPoint(datumLabel->boundingRect().center());
datumLabel->setRotation(toQtDeg(labelAngle));
dimLines->setPath(areaPath);
}
void QGIViewDimension::drawDistance(TechDraw::DrawViewDimension* dimension,
ViewProviderDimension* viewProvider) const
{
@@ -2510,6 +2589,21 @@ void QGIViewDimension::drawAngle(TechDraw::DrawViewDimension* dimension,
dimLines->setPath(anglePath);
}
void QGIViewDimension::drawArea(TechDraw::DrawViewDimension* dimension,
ViewProviderDimension* viewProvider) const
{
Base::BoundBox2d labelRectangle(
fromQtGui(mapRectFromItem(datumLabel, datumLabel->boundingRect())));
areaPoint areaPoint = dimension->getAreaPoint();
double endAngle;
double startRotation;
drawAreaExecutive(
fromQtApp(areaPoint.center), areaPoint.area, labelRectangle, 0.0, viewProvider->StandardAndStyle.getValue(),
viewProvider->RenderingExtent.getValue(), viewProvider->FlipArrowheads.getValue());
}
QColor QGIViewDimension::prefNormalColor()
{
setNormalColor(PreferencesGui::getAccessibleQColor(PreferencesGui::dimQColor()));

View File

@@ -87,6 +87,7 @@ public:
void setPrettyPre();
void setPrettyNormal();
void setColor(QColor color);
void setSelectability(bool val);
QGCustomText* getDimText() { return m_dimText; }
void setDimText(QGCustomText* newText) { m_dimText = newText; }
@@ -232,7 +233,7 @@ protected:
void draw() override;
void resetArrows() const;
void drawArrows(int count, const Base::Vector2d positions[], double angles[], bool flipped) const;
void drawArrows(int count, const Base::Vector2d positions[], double angles[], bool flipped, bool forcePoint = false) const;
void drawSingleLine(QPainterPath &painterPath, const Base::Vector2d &lineOrigin, double lineAngle,
double startPosition, double endPosition) const;
@@ -245,7 +246,7 @@ protected:
void drawDimensionLine(QPainterPath &painterPath, const Base::Vector2d &targetPoint, double lineAngle,
double startPosition, double jointPosition, const Base::BoundBox2d &labelRectangle,
int arrowCount, int standardStyle, bool flipArrows) const;
int arrowCount, int standardStyle, bool flipArrows, bool forcePointStyle = false) const;
void drawDimensionArc(QPainterPath &painterPath, const Base::Vector2d &arcCenter, double arcRadius,
double endAngle, double startRotation, double jointAngle,
const Base::BoundBox2d &labelRectangle, int arrowCount,
@@ -261,10 +262,14 @@ protected:
double endAngle, double startRotation, const Base::BoundBox2d &labelRectangle,
double centerOverhang, int standardStyle, int renderExtent, bool flipArrow) const;
void drawAreaExecutive(const Base::Vector2d &centerPoint, double area, const Base::BoundBox2d &labelRectangle,
double centerOverhang, int standardStyle, int renderExtent, bool flipArrow) const;
void drawDistance(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
void drawRadius(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
void drawDiameter(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
void drawAngle(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
void drawArea(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
QVariant itemChange( GraphicsItemChange change,
const QVariant &value ) override;

View File

@@ -63,6 +63,7 @@
#include "QGVNavStyleTouchpad.h"
#include "QGVPage.h"
#include "Rez.h"
#include "TechDrawHandler.h"
#include "ViewProviderPage.h"
@@ -167,7 +168,7 @@ public:
QGVPage::QGVPage(ViewProviderPage* vpPage, QGSPage* scenePage, QWidget* parent)
: QGraphicsView(parent), m_renderer(Native), drawBkg(true), m_vpPage(nullptr),
m_scene(scenePage), balloonPlacing(false), m_showGrid(false),
m_navStyle(nullptr), d(new Private(this))
m_navStyle(nullptr), d(new Private(this)), toolHandler(nullptr)
{
assert(vpPage);
m_vpPage = vpPage;
@@ -281,6 +282,31 @@ void QGVPage::setNavigationStyle(std::string navParm)
}
}
void QGVPage::activateHandler(TechDrawHandler* newHandler)
{
if (toolHandler) {
toolHandler->deactivate();
}
toolHandler = std::unique_ptr<TechDrawHandler>(newHandler);
toolHandler->activate(this);
// make sure receiver has focus so immediately pressing Escape will be handled by
// ViewProviderSketch::keyPressed() and dismiss the active handler, and not the entire
// sketcher editor
//Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView();
//mdi->setFocus();
}
void QGVPage::deactivateHandler()
{
if (toolHandler) {
toolHandler->deactivate();
toolHandler = nullptr;
}
}
void QGVPage::startBalloonPlacing(DrawView* parent)
{
// Base::Console().Message("QGVP::startBalloonPlacing(%s)\n", parent->getNameInDocument());
@@ -421,7 +447,12 @@ void QGVPage::wheelEvent(QWheelEvent* event)
void QGVPage::keyPressEvent(QKeyEvent* event)
{
m_navStyle->handleKeyPressEvent(event);
if (toolHandler) {
toolHandler->keyPressEvent(event);
}
else {
m_navStyle->handleKeyPressEvent(event);
}
if (!event->isAccepted()) {
QGraphicsView::keyPressEvent(event);
}
@@ -429,7 +460,12 @@ void QGVPage::keyPressEvent(QKeyEvent* event)
void QGVPage::keyReleaseEvent(QKeyEvent* event)
{
m_navStyle->handleKeyReleaseEvent(event);
if (toolHandler) {
toolHandler->keyReleaseEvent(event);
}
else {
m_navStyle->handleKeyReleaseEvent(event);
}
if (!event->isAccepted()) {
QGraphicsView::keyReleaseEvent(event);
}
@@ -465,6 +501,11 @@ void QGVPage::enterEvent(QEvent* event)
void QGVPage::enterEvent(QEnterEvent* event)
#endif
{
if (toolHandler) {
// if the user interacted with another widget than the mdi, the cursor got unset.
// So we reapply it.
toolHandler->updateCursor();
}
QGraphicsView::enterEvent(event);
m_navStyle->handleEnterEvent(event);
QGraphicsView::enterEvent(event);
@@ -478,21 +519,37 @@ void QGVPage::leaveEvent(QEvent* event)
void QGVPage::mousePressEvent(QMouseEvent* event)
{
m_navStyle->handleMousePressEvent(event);
if (toolHandler && (event->button() != Qt::MiddleButton)) {
toolHandler->mousePressEvent(event);
}
else {
m_navStyle->handleMousePressEvent(event);
}
QGraphicsView::mousePressEvent(event);
}
void QGVPage::mouseMoveEvent(QMouseEvent* event)
{
m_navStyle->handleMouseMoveEvent(event);
if (toolHandler) {
toolHandler->mouseMoveEvent(event);
}
else {
m_navStyle->handleMouseMoveEvent(event);
}
QGraphicsView::mouseMoveEvent(event);
}
void QGVPage::mouseReleaseEvent(QMouseEvent* event)
{
m_navStyle->handleMouseReleaseEvent(event);
QGraphicsView::mouseReleaseEvent(event);
resetCursor();
if (toolHandler && (event->button() != Qt::MiddleButton)) {
QGraphicsView::mouseReleaseEvent(event);
toolHandler->mouseReleaseEvent(event);
}
else {
m_navStyle->handleMouseReleaseEvent(event);
QGraphicsView::mouseReleaseEvent(event);
resetCursor();
}
}
TechDraw::DrawPage* QGVPage::getDrawPage() { return m_vpPage->getDrawPage(); }
@@ -553,8 +610,7 @@ void QGVPage::activateCursor(QCursor cursor)
void QGVPage::resetCursor()
{
this->setCursor(Qt::ArrowCursor);
viewport()->setCursor(Qt::ArrowCursor);
activateCursor(Qt::ArrowCursor);
}
void QGVPage::setPanCursor() { activateCursor(panCursor); }

View File

@@ -71,6 +71,7 @@ class QGILeaderLine;
class QGIRichAnno;
class QGITile;
class QGVNavStyle;
class TechDrawHandler;
class TechDrawGuiExport QGVPage: public QGraphicsView
{
@@ -101,6 +102,10 @@ public:
void showGrid(bool state) { m_showGrid = state; }
void updateViewport() { viewport()->repaint(); }
void activateHandler(TechDrawHandler* newHandler);
void deactivateHandler();
bool isHandlerActive() { return toolHandler != nullptr; }
bool isBalloonPlacing() const { return balloonPlacing; }
void setBalloonPlacing(bool isPlacing) { balloonPlacing = isPlacing; }
@@ -196,6 +201,8 @@ private:
MDIViewPage* m_parentMDI;
QContextMenuEvent* m_saveContextEvent;
std::unique_ptr<TechDrawHandler> toolHandler;
};
}// namespace TechDrawGui

View File

@@ -86,10 +86,12 @@
<file>icons/square.svg</file>
<file>icons/TechDraw_3PtAngleDimension.svg</file>
<file>icons/TechDraw_AngleDimension.svg</file>
<file>icons/TechDraw_AreaDimension.svg</file>
<file>icons/TechDraw_Balloon.svg</file>
<file>icons/TechDraw_CameraOrientation.svg</file>
<file>icons/TechDraw_DiameterDimension.svg</file>
<file>icons/TechDraw_Dimension.svg</file>
<file>icons/TechDraw_Dimension_Pointer.svg</file>
<file>icons/TechDraw_DimensionRepair.svg</file>
<file>icons/TechDraw_ExtensionAreaAnnotation.svg</file>
<file>icons/TechDraw_ExtensionArcLengthAnnotation.svg</file>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
height="64"
width="64"
id="svg12"
sodipodi:docname="TechDraw_Dimension_Pointer.svg"
inkscape:version="1.1-beta1 (77e7b44db3, 2021-03-28)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="14.59375"
inkscape:cx="29.910064"
inkscape:cy="29.498929"
inkscape:window-width="3840"
inkscape:window-height="1571"
inkscape:window-x="-9"
inkscape:window-y="-9"
inkscape:window-maximized="1"
inkscape:current-layer="svg12"
objecttolerance="10.0"
gridtolerance="10.0"
guidetolerance="10.0"
inkscape:pageshadow="0"
showgrid="false" />
<defs
id="defs16">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3026"
id="linearGradient927"
x1="16.969255"
y1="39.85923"
x2="58.005249"
y2="39.85923"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3026"
inkscape:collect="always">
<stop
id="stop3028"
offset="0"
style="stop-color:#c4a000;stop-opacity:1" />
<stop
id="stop3030"
offset="1"
style="stop-color:#fce94f;stop-opacity:1" />
</linearGradient>
</defs>
<g
id="crosshair"
style="stroke:#ffffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter"
transform="translate(-0.4111349)">
<path
d="m 16,3 v 9 m 0,8 v 9 M 3,16 h 9 m 8,0 h 9"
id="path9" />
</g>
<g
id="g1123"
transform="matrix(0.92503381,0,0,0.92503381,6.1433162,7.4809763)">
<path
style="fill:none;stroke:#302b00;stroke-width:4;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
id="path3"
sodipodi:type="arc"
sodipodi:cx="42.62447"
sodipodi:cy="32.611259"
sodipodi:rx="16.283468"
sodipodi:ry="16.283468"
sodipodi:start="5.3462224"
sodipodi:end="0.51990659"
sodipodi:arc-type="arc"
sodipodi:open="true"
transform="rotate(12.779233)"
d="m 52.268157,19.490641 a 16.283468,16.283468 0 0 1 4.488175,21.21023" />
<path
style="fill:none;stroke:#302b00;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 54.090138,23.080858 18.968981,44.576119 56.005249,56.637604"
id="path1" />
<path
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
id="path3-6"
sodipodi:type="arc"
sodipodi:cx="42.62447"
sodipodi:cy="32.658588"
sodipodi:rx="16.283468"
sodipodi:ry="16.283468"
sodipodi:start="5.2511532"
sodipodi:end="0.51990659"
sodipodi:arc-type="arc"
sodipodi:open="true"
transform="rotate(12.779233)"
d="M 50.979121,18.681781 A 16.283468,16.283468 0 0 1 56.756332,40.7482" />
<path
style="fill:none;stroke:url(#linearGradient927);stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 54.090138,23.080858 18.968981,44.576119 56.005249,56.637604"
id="path1-3" />
<path
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 54.03712,22.151886 18.920565,43.727975 55.94574,55.594886"
id="path2"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#302b00;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 59.334145,21.127535 49.123924,6.3035436"
id="path4" />
<path
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 59.334145,21.127535 49.123924,6.3035439"
id="path4-7" />
<path
style="fill:none;stroke:#302b00;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 14.780546,48.06322 4.5703249,33.239228"
id="path4-2" />
<path
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 14.780546,48.06322 4.5703248,33.239228"
id="path4-7-9" />
<path
style="fill:none;stroke:#302b00;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 39.969325,13.041079 15.273234,28.142693"
id="path6" />
<path
style="fill:#fce94f;fill-opacity:1;stroke:#302b00;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="m 38.468308,8.9727464 c 9.40717,-0.9537682 9.40717,-0.9537682 9.40717,-0.9537682 l -4.952425,8.2021028 z"
id="path5" />
<path
style="fill:#fce94f;fill-opacity:1;stroke:#302b00;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 16.774251,32.211025 C 7.3670811,33.164794 7.3670811,33.164794 7.3670811,33.164794 L 12.319506,24.96269 Z"
id="path5-1" />
<path
style="fill:none;stroke:#fce94f;stroke-width:2.00001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
d="M 40.879356,12.483498 14.021683,28.964296"
id="path6-2" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@@ -0,0 +1,131 @@
/***************************************************************************
* Copyright (c) 2024 Pierre-Louis Boyer <development@ondsel.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 <cmath>
#include <QGuiApplication>
#include <QPainter>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QTimer>
#include <Inventor/events/SoKeyboardEvent.h>
#endif // #ifndef _PreComp_
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Gui/Application.h>
#include <Gui/CommandT.h>
#include <Gui/MainWindow.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include "MDIViewPage.h"
#include "QGVPage.h"
#include "TechDrawHandler.h"
using namespace TechDrawGui;
/**************************** TechDrawHandler *******************************************/
TechDrawHandler::TechDrawHandler() : Gui::ToolHandler(), viewPage(nullptr)
{}
TechDrawHandler::~TechDrawHandler()
{}
void TechDrawHandler::activate(QGVPage* vp)
{
auto* mdi = dynamic_cast<MDIViewPage*>(Gui::getMainWindow()->activeWindow());
if (!mdi) {
return;
}
mdi->enableContextualMenu(false);
viewPage = vp;
if (!Gui::ToolHandler::activate()) {
viewPage->deactivateHandler();
}
}
void TechDrawHandler::deactivate()
{
Gui::ToolHandler::deactivate();
// The context menu event of MDIViewPage comes after the tool is deactivated.
// So to prevent the menu from appearing when the tool is cleared by right mouse click
// we set a small timer.
QTimer::singleShot(100, [this]() { // 100 milliseconds delay
auto* mdi = dynamic_cast<MDIViewPage*>(Gui::getMainWindow()->activeWindow());
if (!mdi) {
return;
}
mdi->enableContextualMenu(true);
});
}
void TechDrawHandler::keyReleaseEvent(QKeyEvent* event)
{
// the default behaviour is to quit - specific handler categories may
// override this behaviour, for example to implement a continuous mode
if (event->key() == Qt::Key_Escape) {
quit();
event->accept();
}
}
void TechDrawHandler::mouseReleaseEvent(QMouseEvent* event)
{
// the default behaviour is to quit - specific handler categories may
// override this behaviour, for example to implement a continuous mode
if (event->button() == Qt::RightButton) {
quit();
event->accept();
}
}
void TechDrawHandler::quit()
{
viewPage->deactivateHandler();
}
QWidget* TechDrawHandler::getCursorWidget()
{
return viewPage;
}
void TechDrawHandler::setWidgetCursor(QCursor cursor)
{
if (viewPage) {
viewPage->setCursor(cursor);
viewPage->viewport()->setCursor(cursor);
}
}
TechDraw::DrawPage* TechDrawHandler::getPage()
{
return viewPage->getDrawPage();
}

View File

@@ -0,0 +1,67 @@
/***************************************************************************
* Copyright (c) 2024 Pierre-Louis Boyer <development@ondsel.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 *
* *
***************************************************************************/
#ifndef TechDrawGUI_TechDrawHandler_H
#define TechDrawGUI_TechDrawHandler_H
#include <Gui/ToolHandler.h>
#include <Mod/TechDraw/TechDrawGlobal.h>
namespace TechDrawGui
{
class QGVPage;
class TechDrawGuiExport TechDrawHandler : public Gui::ToolHandler
{
public:
TechDrawHandler();
virtual ~TechDrawHandler();
void activate(QGVPage* vPage);
void deactivate() override;
void quit() override;
virtual void mouseMoveEvent(QMouseEvent* event) = 0;
virtual void mousePressEvent(QMouseEvent* event) { Q_UNUSED(event) };
virtual void mouseReleaseEvent(QMouseEvent* event);
virtual void keyPressEvent(QKeyEvent* event) = 0;
virtual void keyReleaseEvent(QKeyEvent* event);
TechDraw::DrawPage* getPage();
protected:
QWidget* getCursorWidget() override;
void setWidgetCursor(QCursor cursor) override;
QGVPage* viewPage;
};
} // namespace TechDrawGui
#endif // TechDrawGUI_TechDrawHandler_H

View File

@@ -196,6 +196,8 @@ void ViewProviderDimension::setPixmapForType()
sPixmap = "TechDraw_AngleDimension";
} else if (getViewObject()->Type.isValue("Angle3Pt")) {
sPixmap = "TechDraw_3PtAngleDimension";
} else if (getViewObject()->Type.isValue("Area")) {
sPixmap = "TechDraw_ExtensionAreaAnnotation";
}
}

View File

@@ -28,6 +28,7 @@
#endif
#include "Workbench.h"
#include <App/Application.h>
#include <Gui/MenuManager.h>
#include <Gui/ToolBarManager.h>
@@ -82,6 +83,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
// dimensions
Gui::MenuItem* dimensions = new Gui::MenuItem;
dimensions->setCommand("Dimensions");
*dimensions << "TechDraw_Dimension";
*dimensions << "TechDraw_LengthDimension";
*dimensions << "TechDraw_HorizontalDimension";
*dimensions << "TechDraw_VerticalDimension";
@@ -89,6 +91,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
*dimensions << "TechDraw_DiameterDimension";
*dimensions << "TechDraw_AngleDimension";
*dimensions << "TechDraw_3PtAngleDimension";
*dimensions << "TechDraw_AreaDimension";
*dimensions << "TechDraw_HorizontalExtentDimension";
*dimensions << "TechDraw_VerticalExtentDimension";
// TechDraw_LinkDimension is DEPRECATED. Use TechDraw_DimensionRepair instead.
@@ -305,14 +308,30 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
Gui::ToolBarItem* dims = new Gui::ToolBarItem(root);
dims->setCommand("TechDraw Dimensions");
*dims << "TechDraw_LengthDimension";
*dims << "TechDraw_HorizontalDimension";
*dims << "TechDraw_VerticalDimension";
*dims << "TechDraw_RadiusDimension";
*dims << "TechDraw_DiameterDimension";
*dims << "TechDraw_AngleDimension";
*dims << "TechDraw_3PtAngleDimension";
*dims << "TechDraw_ExtentGroup";
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/TechDraw/dimensioning");
bool separatedTools = hGrp->GetBool("SeparatedDimensioningTools", true);
if (hGrp->GetBool("SingleDimensioningTool", true)) {
if (separatedTools) {
*dims << "TechDraw_Dimension";
}
else {
*dims << "TechDraw_CompDimensionTools";
}
}
if (separatedTools) {
*dims << "TechDraw_LengthDimension";
*dims << "TechDraw_HorizontalDimension";
*dims << "TechDraw_VerticalDimension";
*dims << "TechDraw_RadiusDimension";
*dims << "TechDraw_DiameterDimension";
*dims << "TechDraw_AngleDimension";
*dims << "TechDraw_3PtAngleDimension";
*dims << "TechDraw_AreaDimension";
*dims << "TechDraw_ExtentGroup";
}
// TechDraw_LinkDimension is DEPRECATED. Use TechDraw_DimensionRepair instead.
// *dims << "TechDraw_LinkDimension";
*dims << "TechDraw_Balloon";
@@ -329,8 +348,10 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
*extattribs << "TechDraw_ExtensionPositionSectionView";
*extattribs << "TechDraw_ExtensionPosChainDimensionGroup";
*extattribs << "TechDraw_ExtensionCascadeDimensionGroup";
*extattribs << "TechDraw_ExtensionAreaAnnotation";
*extattribs << "TechDraw_ExtensionArcLengthAnnotation";
if (separatedTools) {
*extattribs << "TechDraw_ExtensionAreaAnnotation";
*extattribs << "TechDraw_ExtensionArcLengthAnnotation";
}
*extattribs << "TechDraw_ExtensionCustomizeFormat";
Gui::ToolBarItem* extcenter = new Gui::ToolBarItem(root);
@@ -344,10 +365,12 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
Gui::ToolBarItem* extdimensions = new Gui::ToolBarItem(root);
extdimensions->setCommand("TechDraw Extend Dimensions");
*extdimensions << "TechDraw_ExtensionCreateChainDimensionGroup";
*extdimensions << "TechDraw_ExtensionCreateCoordDimensionGroup";
*extdimensions << "TechDraw_ExtensionChamferDimensionGroup";
*extdimensions << "TechDraw_ExtensionCreateLengthArc";
if (separatedTools) {
*extdimensions << "TechDraw_ExtensionCreateChainDimensionGroup";
*extdimensions << "TechDraw_ExtensionCreateCoordDimensionGroup";
*extdimensions << "TechDraw_ExtensionChamferDimensionGroup";
*extdimensions << "TechDraw_ExtensionCreateLengthArc";
}
*extdimensions << "TechDraw_ExtensionInsertPrefixGroup";
*extdimensions << "TechDraw_ExtensionIncreaseDecreaseGroup";
@@ -406,6 +429,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const
Gui::ToolBarItem* dims = new Gui::ToolBarItem(root);
dims->setCommand("TechDraw Dimensions");
*dims << "TechDraw_Dimension";
*dims << "TechDraw_LengthDimension";
*dims << "TechDraw_HorizontalDimension";
*dims << "TechDraw_VerticalDimension";