[TD]SectionView/ComplexSection - preview, direction selection

- add preview/live update to TaskSectionView & TaskComplexSection
- add view direction selector to uis
- use SectionNormal as Direction.  Make Direction read-only
- simplify section line end point calculation
- section group command in toolbar
- make section and complex section icons consistent
- fix compsolid cutting tool
- terminology: single/piecewise to offset/aligned
This commit is contained in:
wandererfan
2022-10-13 10:59:54 -04:00
committed by WandererFan
parent 5ddc6ce789
commit 99f67b8a40
27 changed files with 4104 additions and 1390 deletions

View File

@@ -226,6 +226,12 @@ SET(TechDrawGui_SRCS
TaskComplexSection.cpp
TaskComplexSection.h
TaskComplexSection.ui
Widgets/CompassDialWidget.cpp
Widgets/CompassDialWidget.h
Widgets/CompassWidget.cpp
Widgets/CompassWidget.h
Widgets/VectorEditWidget.cpp
Widgets/VectorEditWidget.h
)
SET(TechDrawGuiView_SRCS

View File

@@ -21,10 +21,11 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QFileInfo>
# include <QMessageBox>
# include <sstream>
# include <vector>
#include <QApplication>
#include <QFileInfo>
#include <QMessageBox>
#include <sstream>
#include <vector>
#endif
#include <App/Document.h>
@@ -36,6 +37,7 @@
#include <Gui/Action.h>
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Command.h>
#include <Gui/Control.h>
#include <Gui/Document.h>
@@ -76,6 +78,8 @@
#include "ViewProviderViewPart.h"
#include "TaskSectionView.h"
void execSimpleSection(Gui::Command* cmd);
void execComplexSection(Gui::Command* cmd);
class Vertex;
using namespace TechDrawGui;
@@ -469,6 +473,98 @@ bool CmdTechDrawActiveView::isActive()
return DrawGuiUtil::needPage(this, true);
}
//===========================================================================
// TechDraw_SectionGroup
//===========================================================================
DEF_STD_CMD_ACL(CmdTechDrawSectionGroup)
CmdTechDrawSectionGroup::CmdTechDrawSectionGroup()
: Command("TechDraw_SectionGroup")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert a simple or complex Section View");
sToolTipText = sMenuText;
sWhatsThis = "TechDraw_SectionGroup";
sStatusTip = sToolTipText;
}
void CmdTechDrawSectionGroup::activated(int iMsg)
{
// Base::Console().Message("CMD::SectionGrp - 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:
execSimpleSection(this);
break;
case 1:
execComplexSection(this);
break;
default:
Base::Console().Message("CMD::SectionGrp - invalid iMsg: %d\n", iMsg);
};
}
Gui::Action * CmdTechDrawSectionGroup::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("actions/TechDraw_SectionView"));
p1->setObjectName(QString::fromLatin1("TechDraw_SectionView"));
p1->setWhatsThis(QString::fromLatin1("TechDraw_SectionView"));
QAction* p2 = pcAction->addAction(QString());
p2->setIcon(Gui::BitmapFactory().iconFromTheme("actions/TechDraw_ComplexSection"));
p2->setObjectName(QString::fromLatin1("TechDraw_ComplexSection"));
p2->setWhatsThis(QString::fromLatin1("TechDraw_ComplexSection"));
_pcAction = pcAction;
languageChange();
pcAction->setIcon(p1->icon());
int defaultId = 0;
pcAction->setProperty("defaultAction", QVariant(defaultId));
return pcAction;
}
void CmdTechDrawSectionGroup::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("CmdTechDrawSectionGroup", "Section View"));
arc1->setToolTip(QApplication::translate("TechDraw_SectionView", "Insert simple Section View"));
arc1->setStatusTip(arc1->toolTip());
QAction* arc2 = a[1];
arc2->setText(QApplication::translate("CmdTechDrawSectionGroup", "Complex Section"));
arc2->setToolTip(QApplication::translate("TechDraw_ComplexSection", "Insert complex Section View"));
arc2->setStatusTip(arc2->toolTip());
}
bool CmdTechDrawSectionGroup::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, false);
return (havePage && haveView);
}
//===========================================================================
// TechDraw_SectionView
//===========================================================================
@@ -490,22 +586,14 @@ CmdTechDrawSectionView::CmdTechDrawSectionView()
void CmdTechDrawSectionView::activated(int iMsg)
{
Q_UNUSED(iMsg);
TechDraw::DrawPage* page = DrawGuiUtil::findPage(this);
if (!page) {
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;
}
std::vector<App::DocumentObject*> baseObj = getSelection().getObjectsOfType(TechDraw::DrawViewPart::getClassTypeId());
if (baseObj.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select at least 1 DrawViewPart object as Base."));
return;
}
TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(*baseObj.begin());
Gui::Control().showDialog(new TaskDlgSectionView(dvp));
updateActive(); //ok here since dialog doesn't call doc.recompute()
commitCommand();
execSimpleSection(this);
}
bool CmdTechDrawSectionView::isActive()
@@ -519,6 +607,26 @@ bool CmdTechDrawSectionView::isActive()
return (havePage && haveView && !taskInProgress);
}
void execSimpleSection(Gui::Command* cmd)
{
TechDraw::DrawPage* page = DrawGuiUtil::findPage(cmd);
if (!page) {
return;
}
std::vector<App::DocumentObject*> baseObj = cmd->getSelection().getObjectsOfType(TechDraw::DrawViewPart::getClassTypeId());
if (baseObj.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select at least 1 DrawViewPart object as Base."));
return;
}
TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(*baseObj.begin());
Gui::Control().showDialog(new TaskDlgSectionView(dvp));
cmd->updateActive(); //ok here since dialog doesn't call doc.recompute()
cmd->commitCommand();
}
//===========================================================================
// TechDraw_ComplexSection
//===========================================================================
@@ -540,7 +648,26 @@ CmdTechDrawComplexSection::CmdTechDrawComplexSection()
void CmdTechDrawComplexSection::activated(int iMsg)
{
Q_UNUSED(iMsg);
TechDraw::DrawPage* page = DrawGuiUtil::findPage(this);
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;
}
execComplexSection(this);
}
bool CmdTechDrawComplexSection::isActive()
{
return DrawGuiUtil::needPage(this);
}
//Complex Sections can be created without a baseView, so the gathering of input
//for the dialog is more involved that simple section
void execComplexSection(Gui::Command* cmd)
{
TechDraw::DrawPage* page = DrawGuiUtil::findPage(cmd);
if (!page) {
return;
}
@@ -553,7 +680,7 @@ void CmdTechDrawComplexSection::activated(int iMsg)
std::vector<std::string> profileSubs;
Gui::ResolveMode resolve = Gui::ResolveMode::OldStyleElement; //mystery
bool single = false; //mystery
auto selection = getSelection().getSelectionEx(nullptr,
auto selection = cmd->getSelection().getSelectionEx(nullptr,
App::DocumentObject::getClassTypeId(),
resolve,
single);
@@ -581,11 +708,11 @@ void CmdTechDrawComplexSection::activated(int iMsg)
}
// If parent of the obj is a link to another document, we possibly need to treat non-link obj as linked, too
// 1st, is obj in another document?
if (obj->getDocument() != this->getDocument()) {
if (obj->getDocument() != cmd->getDocument()) {
std::set<App::DocumentObject*> parents = obj->getInListEx(true);
for (auto& parent : parents) {
// Only consider parents in the current document, i.e. possible links in this View's document
if (parent->getDocument() != this->getDocument()) {
if (parent->getDocument() != cmd->getDocument()) {
continue;
}
// 2nd, do we really have a link to obj?
@@ -628,11 +755,6 @@ void CmdTechDrawComplexSection::activated(int iMsg)
profileObject, profileSubs));
}
bool CmdTechDrawComplexSection::isActive()
{
return DrawGuiUtil::needPage(this);
}
//===========================================================================
// TechDraw_DetailView
//===========================================================================
@@ -835,63 +957,6 @@ bool CmdTechDrawProjectionGroup::isActive()
return (havePage && !taskInProgress);
}
//===========================================================================
// TechDraw_NewMulti **deprecated**
//===========================================================================
//DEF_STD_CMD_A(CmdTechDrawNewMulti);
//CmdTechDrawNewMulti::CmdTechDrawNewMulti()
// : Command("TechDraw_NewMulti")
//{
// sAppModule = "TechDraw";
// sGroup = QT_TR_NOOP("TechDraw");
// sMenuText = QT_TR_NOOP("Insert multi-part view in drawing");
// sToolTipText = QT_TR_NOOP("Insert a new View of a multiple Parts in the active drawing");
// sWhatsThis = "TechDraw_NewMulti";
// sStatusTip = sToolTipText;
// sPixmap = "actions/TechDraw_Multiview";
//}
//void CmdTechDrawNewMulti::activated(int iMsg)
//{
// Q_UNUSED(iMsg);
// TechDraw::DrawPage* page = DrawGuiUtil::findPage(this);
// if (!page) {
// return;
// }
// std::vector<App::DocumentObject*> shapes = getSelection().getObjectsOfType(App::DocumentObject::getClassTypeId());
// if (shapes.empty()) {
// QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
// QObject::tr("Can not MultiView from this selection."));
// return;
// }
// std::string PageName = page->getNameInDocument();
// Gui::WaitCursor wc;
// openCommand(QT_TRANSLATE_NOOP("Command", "Create view"));
// std::string FeatName = getUniqueObjectName("MultiView");
// doCommand(Doc, "App.activeDocument().addObject('TechDraw::DrawViewMulti', '%s')", FeatName.c_str());
// App::DocumentObject *docObj = getDocument()->getObject(FeatName.c_str());
// auto multiView( static_cast<TechDraw::DrawViewMulti *>(docObj) );
// multiView->Sources.setValues(shapes);
// doCommand(Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
// updateActive();
// commitCommand();
//}
//bool CmdTechDrawNewMulti::isActive(void)
//{
// return DrawGuiUtil::needPage(this);
//}
//===========================================================================
// TechDraw_Balloon
//===========================================================================
//! common checks of Selection for Dimension commands
//non-empty selection, no more than maxObjs selected and at least 1 DrawingPage exists
bool _checkSelectionBalloon(Gui::Command* cmd, unsigned maxObjs) {
@@ -1617,7 +1682,9 @@ void CreateTechDrawCommands()
rcCmdMgr.addCommand(new CmdTechDrawPrintAll());
rcCmdMgr.addCommand(new CmdTechDrawView());
rcCmdMgr.addCommand(new CmdTechDrawActiveView());
rcCmdMgr.addCommand(new CmdTechDrawSectionGroup());
rcCmdMgr.addCommand(new CmdTechDrawSectionView());
rcCmdMgr.addCommand(new CmdTechDrawComplexSection());
rcCmdMgr.addCommand(new CmdTechDrawDetailView());
rcCmdMgr.addCommand(new CmdTechDrawProjectionGroup());
rcCmdMgr.addCommand(new CmdTechDrawClipGroup());
@@ -1631,5 +1698,4 @@ void CreateTechDrawCommands()
rcCmdMgr.addCommand(new CmdTechDrawSpreadsheetView());
rcCmdMgr.addCommand(new CmdTechDrawBalloon());
rcCmdMgr.addCommand(new CmdTechDrawProjectShape());
rcCmdMgr.addCommand(new CmdTechDrawComplexSection());
}

View File

@@ -912,15 +912,15 @@ void QGIViewPart::drawComplexSectionLine(TechDraw::DrawViewSection* viewSection,
} else {
sectionLine->clearChangePoints();
}
if (dcs->ProjectionStrategy.isValue("Single")) {
Base::Vector3d arrowDirSingle = viewSection->SectionNormal.getValue();
arrowDirSingle = - viewPart->projectPoint(arrowDirSingle); //arrows are opposite section normal
sectionLine->setDirection(arrowDirSingle.x, -arrowDirSingle.y); //invert y for Qt
if (dcs->ProjectionStrategy.isValue("Offset")) {
Base::Vector3d arrowDirOffset = viewSection->SectionNormal.getValue();
arrowDirOffset = - viewPart->projectPoint(arrowDirOffset); //arrows are opposite section normal
sectionLine->setDirection(arrowDirOffset.x, -arrowDirOffset.y); //invert y for Qt
} else {
std::pair<Base::Vector3d, Base::Vector3d> dirsPiecewise = dcs->sectionArrowDirs();
dirsPiecewise.first = DrawUtil::invertY(dirsPiecewise.first);
dirsPiecewise.second = DrawUtil::invertY(dirsPiecewise.second);
sectionLine->setArrowDirections(dirsPiecewise.first, dirsPiecewise.second);
std::pair<Base::Vector3d, Base::Vector3d> dirsAligned = dcs->sectionArrowDirs();
dirsAligned.first = DrawUtil::invertY(dirsAligned.first);
dirsAligned.second = DrawUtil::invertY(dirsAligned.second);
sectionLine->setArrowDirections(dirsAligned.first, dirsAligned.second);
}
//set the general parameters

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -25,6 +25,7 @@
#ifndef _PreComp_
#endif // #ifndef _PreComp_
#include <QMessageBox>
#include <QPushButton>
#include <BRep_Tool.hxx>
@@ -55,9 +56,12 @@
#include <Mod/TechDraw/App/DrawViewPart.h>
#include <Mod/TechDraw/App/DrawComplexSection.h>
#include <Mod/TechDraw/App/Preferences.h>
#include <Mod/TechDraw/Gui/ui_TaskComplexSection.h>
#include "DrawGuiUtil.h"
#include "Widgets/CompassWidget.h"
#include "Widgets/VectorEditWidget.h"
#include "TaskComplexSection.h"
@@ -65,6 +69,7 @@ using namespace Gui;
using namespace TechDraw;
using namespace TechDrawGui;
//ctor for creation
TaskComplexSection::TaskComplexSection(TechDraw::DrawPage* page,
TechDraw::DrawViewPart* baseView,
std::vector<App::DocumentObject*> shapes,
@@ -79,46 +84,200 @@ TaskComplexSection::TaskComplexSection(TechDraw::DrawPage* page,
m_xShapes(xShapes),
m_profileObject(profileObject),
m_profileSubs(profileSubs),
m_sectionName(std::string())
m_dirName("Aligned"),
m_createMode(true),
m_applyDeferred(0),
m_angle(0.0)
{
m_sectionName = std::string();
m_doc = m_baseView->getDocument();
m_saveBaseName = m_baseView->getNameInDocument();
m_savePageName = m_baseView->findParentPage()->getNameInDocument();
m_localUnit = Base::Vector3d(0.0, 1.0, 0.0);
ui->setupUi(this);
saveSectionState();
setUiPrimary();
connect(ui->pbSectionObjects, SIGNAL(clicked()), this, SLOT(onSectionObjectsUseSelectionClicked()));
connect(ui->pbProfileObject, SIGNAL(clicked()), this, SLOT(onProfileObjectsUseSelectionClicked()));
m_applyDeferred = 0; //setting the direction widgets causes an increment of the deferred count,
//so we reset the counter and the message.
ui->lPendingUpdates->setText(QString());
}
void TaskComplexSection::changeEvent(QEvent* event)
//ctor for edit
TaskComplexSection::TaskComplexSection(TechDraw::DrawComplexSection* complexSection) :
ui(new Ui_TaskComplexSection),
m_page(nullptr),
m_baseView(nullptr),
m_section(complexSection),
m_profileObject(nullptr),
m_dirName("Aligned"),
m_createMode(false),
m_applyDeferred(0),
m_angle(0.0)
{
if (event->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
m_sectionName = m_section->getNameInDocument();
m_doc = m_section->getDocument();
m_baseView = dynamic_cast<TechDraw::DrawViewPart*> (m_section->BaseView.getValue());
if (m_baseView) {
m_saveBaseName = m_baseView->getNameInDocument();
m_savePageName = m_baseView->findParentPage()->getNameInDocument();
}
m_shapes = m_section->Source.getValues();
m_xShapes = m_section->XSource.getValues();
m_profileObject = m_section->CuttingToolWireObject.getValue();
m_localUnit = Base::Vector3d(0.0, 1.0, 0.0);
ui->setupUi(this);
saveSectionState();
setUiEdit();
m_applyDeferred = 0; //setting the direction widgets causes an increment of the deferred count,
//so we reset the counter and the message.
ui->lPendingUpdates->setText(QString());
}
void TaskComplexSection::setUiPrimary()
{
setWindowTitle(QObject::tr("New Complex Section"));
if (m_baseView) {
ui->sbScale->setValue(m_baseView->getScale());
ui->cmbScaleType->setCurrentIndex(m_baseView->ScaleType.getValue());
} else {
ui->sbScale->setValue(Preferences::scale());
ui->cmbScaleType->setCurrentIndex(Preferences::scaleType());
}
ui->cmbStrategy->setCurrentIndex(0);
ui->dsbXNormal->setEnabled(true);
ui->dsbYNormal->setEnabled(true);
ui->dsbZNormal->setEnabled(true);
std::pair<Base::Vector3d, Base::Vector3d> dirs = DrawGuiUtil::get3DDirAndRot();
ui->dsbXNormal->setValue(dirs.first.x);
ui->dsbYNormal->setValue(dirs.first.y);
ui->dsbZNormal->setValue(dirs.first.z);
m_saveXDir = dirs.second;
setUiCommon();
if (m_baseView) {
ui->leBaseView->setText(Base::Tools::fromStdString(m_baseView->getNameInDocument()));
//if there is a baseView, we don't know the sectionNormal yet and have to wait until
//one is picked in the dialog
Base::Vector3d defaultNormal(-1.0, 0.0, 0.0);
m_saveNormal = defaultNormal;
m_localUnit = defaultNormal;
m_saveXDir = Base::Vector3d(0.0, 1.0, 0.0);
ui->leBaseView->setText(Base::Tools::fromStdString(m_baseView->getNameInDocument()));
m_viewDirectionWidget->setValue(defaultNormal * -1.0);
} else {
//if there is no baseView, we use the 3d view to determine the SectionNormal
//and XDirection.
std::pair<Base::Vector3d, Base::Vector3d> dirs = DrawGuiUtil::get3DDirAndRot();
m_saveNormal = dirs.first;
m_localUnit = dirs.first;
m_saveXDir = dirs.second;
m_viewDirectionWidget->setValue(m_saveNormal * -1.0); //this will propogate to m_compass
}
}
void TaskComplexSection::setUiEdit()
{
setWindowTitle(QObject::tr("Edit Complex Section"));
if (m_baseView) {
ui->leBaseView->setText(Base::Tools::fromStdString(m_baseView->getNameInDocument()));
}
ui->cmbStrategy->setCurrentIndex(m_section->ProjectionStrategy.getValue());
ui->leSymbol->setText(Base::Tools::fromStdString(m_section->SectionSymbol.getValue()));
ui->sbScale->setValue(m_section->Scale.getValue());
ui->cmbScaleType->setCurrentIndex(m_section->ScaleType.getValue());
setUiCommon();
Base::Vector3d sectionNormalVec = m_section->SectionNormal.getValue();
if (m_baseView) {
ui->leBaseView->setText(Base::Tools::fromStdString(m_baseView->getNameInDocument()));
Base::Vector3d projectedViewDirection = m_baseView->projectPoint(sectionNormalVec, false);
double viewAngle = atan2(-projectedViewDirection.y,
-projectedViewDirection.x);
m_compass->setDialAngle(viewAngle * 180.0 / M_PI);
m_viewDirectionWidget->setValue(projectedViewDirection * -1.0);
} else {
//no local angle makes sense if there is no baseView?
m_viewDirectionWidget->setValue(sectionNormalVec * -1.0);
}
}
void TaskComplexSection::setUiCommon()
{
ui->leSectionObjects->setText(sourcesToString());
ui->leProfileObject->setText(Base::Tools::fromStdString(m_profileObject->getNameInDocument()) +
QString::fromUtf8(" / ") +
Base::Tools::fromStdString(m_profileObject->Label.getValue()));
if (m_baseView) {
ui->dsbScale->setValue(m_baseView->getScale());
ui->cmbScaleType->setCurrentIndex(m_baseView->ScaleType.getValue());
} else {
ui->dsbScale->setValue(Preferences::scale());
ui->cmbScaleType->setCurrentIndex(Preferences::scaleType());
m_compass = new CompassWidget(this);
auto layout = ui->compassLayout;
layout->addWidget(m_compass);
m_viewDirectionWidget = new VectorEditWidget(this);
m_viewDirectionWidget->setLabel(QObject::tr("Current View Direction"));
auto editLayout = ui->viewDirectionLayout;
editLayout->addWidget(m_viewDirectionWidget);
connect(ui->pbRight, SIGNAL(clicked(bool)), m_compass, SLOT(setToEast()));
connect(ui->pbLeft, SIGNAL(clicked(bool)), m_compass, SLOT(setToWest()));
connect(ui->pbUp, SIGNAL(clicked(bool)), m_compass, SLOT(setToNorth()));
connect(ui->pbDown, SIGNAL(clicked(bool)), m_compass, SLOT(setToSouth()));
connect(m_compass, SIGNAL(angleChanged(double)), this, SLOT(slotChangeAngle(double)));
connect(ui->pbUp, SIGNAL(clicked(bool)), this, SLOT(onUpClicked()));
connect(ui->pbDown, SIGNAL(clicked(bool)), this, SLOT(onDownClicked()));
connect(ui->pbRight, SIGNAL(clicked(bool)), this, SLOT(onRightClicked()));
connect(ui->pbLeft, SIGNAL(clicked(bool)), this, SLOT(onLeftClicked()));
connect(ui->pbUpdateNow, SIGNAL(clicked(bool)), this, SLOT(updateNowClicked()));
connect(ui->cbLiveUpdate, SIGNAL(clicked(bool)), this, SLOT(liveUpdateClicked()));
connect(ui->pbSectionObjects, SIGNAL(clicked()), this, SLOT(onSectionObjectsUseSelectionClicked()));
connect(ui->pbProfileObject, SIGNAL(clicked()), this, SLOT(onProfileObjectsUseSelectionClicked()));
connect(m_compass, SIGNAL(angleChanged(double)), this, SLOT(slotChangeAngle(double)));
connect(m_viewDirectionWidget, SIGNAL(valueChanged(Base::Vector3d)),
this, SLOT(slotViewDirectionChanged(Base::Vector3d)));
}
//save the start conditions
void TaskComplexSection::saveSectionState()
{
// Base::Console().Message("TCS::saveSectionState()\n");
if (m_section) {
m_saveSymbol = m_section->SectionSymbol.getValue();
m_saveScale = m_section->getScale();
m_saveScaleType = m_section->ScaleType.getValue();
m_saveNormal = m_section->SectionNormal.getValue();
m_saveDirection = m_section->Direction.getValue();
m_localUnit = m_saveNormal;
m_saveXDir = m_section->XDirection.getValue();
m_saveOrigin = m_section->SectionOrigin.getValue();
m_saveDirName = m_section->SectionDirection.getValueAsString();
m_saved = true;
}
if (m_baseView) {
m_shapes = m_baseView->Source.getValues();
m_xShapes = m_baseView->XSource.getValues();
}
}
//restore the start conditions
void TaskComplexSection::restoreSectionState()
{
// Base::Console().Message("TCS::restoreSectionState()\n");
if (!m_section)
return;
m_section->SectionSymbol.setValue(m_saveSymbol);
m_section->Scale.setValue(m_saveScale);
m_section->ScaleType.setValue(m_saveScaleType);
m_section->SectionNormal.setValue(m_saveNormal);
m_section->Direction.setValue(m_saveDirection);
m_section->XDirection.setValue(m_saveXDir);
m_section->SectionOrigin.setValue(m_saveOrigin);
m_section->SectionDirection.setValue(m_saveDirName.c_str());
}
void TaskComplexSection::onSectionObjectsUseSelectionClicked()
@@ -140,6 +299,78 @@ void TaskComplexSection::onSectionObjectsUseSelectionClicked()
ui->leSectionObjects->setText(sourcesToString());
}
//the VectorEditWidget reports a change in direction
void TaskComplexSection::slotViewDirectionChanged(Base::Vector3d newDirection)
{
// Base::Console().Message("TCS::slotViewDirectionChanged(%s)\n",
// DrawUtil::formatVector(newDirection).c_str());
Base::Vector3d projectedViewDirection = m_baseView->projectPoint(newDirection, false);
projectedViewDirection.Normalize();
double viewAngle = atan2(projectedViewDirection.y,
projectedViewDirection.x);
m_compass->setDialAngle(viewAngle * 180.0 / M_PI);
checkAll(false);
applyAligned(projectedViewDirection);
}
//the CompassWidget reports the view direction. This is the reverse of the
//SectionNormal
void TaskComplexSection::slotChangeAngle(double newAngle)
{
// Base::Console().Message("TCS::slotAngleChanged(%.3f)\n", newAngle);
double angleRadians = newAngle * M_PI / 180.0;
if (m_baseView) {
double unitX = cos(angleRadians);
double unitY = sin(angleRadians);
Base::Vector3d localUnit(unitX, unitY, 0.0);
m_viewDirectionWidget->setValue(localUnit);
checkAll(false);
applyAligned(localUnit);
} else {
//save the angle for later use
m_angle = angleRadians;
}
}
void TaskComplexSection::onUpClicked()
{
// Base::Console().Message("TCS::onUpClicked()\n");
checkAll(false);
applyAligned(Base::Vector3d(0.0, 1.0, 0.0));
}
void TaskComplexSection::onDownClicked()
{
// Base::Console().Message("TCS::onDownClicked()\n");
checkAll(false);
applyAligned(Base::Vector3d(0.0, -1.0, 0.0));
}
void TaskComplexSection::onLeftClicked()
{
// Base::Console().Message("TCS::onLeftClicked()\n");
checkAll(false);
applyAligned(Base::Vector3d(-1.0, 0.0, 0.0));
}
void TaskComplexSection::onRightClicked()
{
// Base::Console().Message("TCS::onRightClicked()\n");
checkAll(false);
applyAligned(Base::Vector3d(1.0, 0.0, 0.0));
}
void TaskComplexSection::onIdentifierChanged()
{
checkAll(false);
apply();
}
void TaskComplexSection::onScaleChanged()
{
checkAll(false);
apply();
}
void TaskComplexSection::onProfileObjectsUseSelectionClicked()
{
std::vector<Gui::SelectionObject> selection = Gui::Selection().getSelectionEx();
@@ -151,44 +382,155 @@ void TaskComplexSection::onProfileObjectsUseSelectionClicked()
Base::Tools::fromStdString(m_profileObject->Label.getValue()));
}
}
void TaskComplexSection::scaleTypeChanged(int index)
{
if (index == 0) {
// Page Scale Type
ui->sbScale->setEnabled(false);
if (m_baseView->findParentPage()) {
ui->sbScale->setValue(m_baseView->findParentPage()->Scale.getValue());
ui->sbScale->setEnabled(false);
}
} else if (index == 1) {
// Automatic Scale Type
ui->sbScale->setEnabled(false);
if (m_section) {
ui->sbScale->setValue(m_section->autoScale());
}
} else if (index == 2) {
// Custom Scale Type
ui->sbScale->setEnabled(true);
if (m_section) {
ui->sbScale->setValue(m_section->Scale.getValue());
ui->sbScale->setEnabled(true);
}
} else {
Base::Console().Log("Error - TaskComplexSection::scaleTypeChanged - unknown scale type: %d\n", index);
return;
}
}
void TaskComplexSection::checkAll(bool check)
{
ui->pbUp->setChecked(check);
ui->pbDown->setChecked(check);
ui->pbRight->setChecked(check);
ui->pbLeft->setChecked(check);
}
void TaskComplexSection::enableAll(bool enable)
{
ui->leSymbol->setEnabled(enable);
ui->sbScale->setEnabled(enable);
ui->cmbScaleType->setEnabled(enable);
QString qScaleType = ui->cmbScaleType->currentText();
//Allow or prevent scale changing initially
if (qScaleType == QString::fromUtf8("Custom")) {
ui->sbScale->setEnabled(true);
}
else {
ui->sbScale->setEnabled(false);
}
}
void TaskComplexSection::liveUpdateClicked() {
apply(true);
}
void TaskComplexSection::updateNowClicked() {
apply(true);
}
QString TaskComplexSection::sourcesToString()
{
QString result;
QString separator(QString::fromUtf8(", "));
QString currentSeparator;
if (m_baseView) {
for (auto& obj : m_baseView->Source.getValues()) {
result += Base::Tools::fromStdString(obj->getNameInDocument()) +
result += currentSeparator +
Base::Tools::fromStdString(obj->getNameInDocument()) +
QString::fromUtf8(" / ") +
Base::Tools::fromStdString(obj->Label.getValue()) +
QString::fromUtf8(", ");
Base::Tools::fromStdString(obj->Label.getValue());
currentSeparator = separator;
}
currentSeparator = QString();
for (auto& obj : m_baseView->XSource.getValues()) {
result += Base::Tools::fromStdString(obj->getNameInDocument()) +
result += currentSeparator +
Base::Tools::fromStdString(obj->getNameInDocument()) +
QString::fromUtf8(" / ") +
Base::Tools::fromStdString(obj->Label.getValue()) +
QString::fromUtf8(", ");
Base::Tools::fromStdString(obj->Label.getValue());
}
} else {
for (auto& obj : m_shapes) {
result += Base::Tools::fromStdString(obj->getNameInDocument()) +
result += currentSeparator +
Base::Tools::fromStdString(obj->getNameInDocument()) +
QString::fromUtf8(" / ") +
Base::Tools::fromStdString(obj->Label.getValue()) +
QString::fromUtf8(", ");
Base::Tools::fromStdString(obj->Label.getValue());
}
currentSeparator = QString();
for (auto& obj : m_xShapes) {
result += Base::Tools::fromStdString(obj->getNameInDocument()) +
result += currentSeparator +
Base::Tools::fromStdString(obj->getNameInDocument()) +
QString::fromUtf8(" / ") +
Base::Tools::fromStdString(obj->Label.getValue()) +
QString::fromUtf8(", ");
Base::Tools::fromStdString(obj->Label.getValue());
}
}
return result;
}
void TaskComplexSection::updateUi()
//******************************************************************************
bool TaskComplexSection::apply(bool forceUpdate)
{
// Base::Console().Message("TCS::apply() - liveUpdate: %d forece: %d\n",
// ui->cbLiveUpdate->isChecked(), forceUpdate);
if(!ui->cbLiveUpdate->isChecked() &&
!forceUpdate) {
//nothing to do
m_applyDeferred++;
QString msgLiteral = QString::fromUtf8(QT_TRANSLATE_NOOP("TaskPojGroup", " updates pending"));
QString msgNumber = QString::number(m_applyDeferred);
ui->lPendingUpdates->setText(msgNumber + msgLiteral);
return false;
}
Gui::WaitCursor wc;
if (!m_section) {
createComplexSection();
}
if (isSectionValid()) {
updateComplexSection();
} else {
failNoObject();
}
m_section->recomputeFeature();
if (isBaseValid()) {
m_baseView->requestPaint();
}
enableAll(true);
checkAll(false);
wc.restoreCursor();
m_applyDeferred = 0;
ui->lPendingUpdates->setText(QString());
return true;
}
void TaskComplexSection::applyAligned(Base::Vector3d localUnit)
{
// Base::Console().Message("TCS::applyAligned(%s)\n",
// DrawUtil::formatVector(localUnit).c_str());
m_dirName = "Aligned";
m_localUnit = localUnit;
enableAll(true);
apply();
}
//*******************************************************************
//pointer to created view is not returned, but stored in m_section
void TaskComplexSection::createComplexSection()
{
@@ -219,7 +561,7 @@ void TaskComplexSection::createComplexSection()
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.Scale = %0.6f",
m_sectionName.c_str(),
ui->dsbScale->value());
ui->sbScale->value());
int scaleType = ui->cmbScaleType->currentIndex();
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.ScaleType = %d",
m_sectionName.c_str(), scaleType);
@@ -227,14 +569,6 @@ void TaskComplexSection::createComplexSection()
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.ProjectionStrategy = %d",
m_sectionName.c_str(), projectionStrategy);
Command::doCommand(Command::Doc, "App.activeDocument().%s.Direction = FreeCAD.Vector(%.3f, %.3f, %.3f)",
m_sectionName.c_str(), ui->dsbXNormal->value(),
ui->dsbYNormal->value(), ui->dsbZNormal->value());
Command::doCommand(Command::Doc, "App.activeDocument().%s.SectionNormal = FreeCAD.Vector(%.3f, %.3f, %.3f)",
m_sectionName.c_str(), ui->dsbXNormal->value(),
ui->dsbYNormal->value(), ui->dsbZNormal->value());
Command::doCommand(Command::Doc, "App.activeDocument().%s.XDirection = FreeCAD.Vector(%.3f, %.3f, %.3f)",
m_sectionName.c_str(), m_saveXDir.x, m_saveXDir.y, m_saveXDir.z);
Command::doCommand(Command::Doc, "App.activeDocument().%s.SectionOrigin = FreeCAD.Vector(0.0, 0.0, 0.0)",
m_sectionName.c_str());
Command::doCommand(Command::Doc, "App.activeDocument().%s.SectionDirection = 'Aligned'",
@@ -246,62 +580,181 @@ void TaskComplexSection::createComplexSection()
throw Base::RuntimeError("TaskComplexSection - new section object not found");
}
if (m_baseView) {
m_section->Source.setValues(m_baseView->Source.getValues());
m_section->XSource.setValues(m_baseView->XSource.getValues());
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.BaseView = App.ActiveDocument.%s",
m_sectionName.c_str(), m_baseView->getNameInDocument());
if (m_localUnit.Length() != 0.0) {
m_section->setCSFromBase(m_localUnit * -1.0);
}
m_section->Source.setValues(m_baseView->Source.getValues());
m_section->XSource.setValues(m_baseView->XSource.getValues());
} else {
//if we have not changed the direction, we should use the 3d directions saved in the
//constructor
if (m_localUnit.IsEqual(m_saveNormal, EWTOLERANCE)) {
m_section->SectionNormal.setValue(m_saveNormal);
m_section->XDirection.setValue(m_saveXDir);
} else {
//if we have changed the direction, use the local unit to create a CS
m_section->setCSFromLocalUnit(m_localUnit * -1.0);
m_localUnit = m_saveNormal; //don't repeat this work next time through
}
m_section->Source.setValues(m_shapes);
m_section->XSource.setValues(m_xShapes);
}
m_section->CuttingToolWireObject.setValue(m_profileObject);
m_section->SectionDirection.setValue("Aligned");
m_section->Source.setValues(m_shapes);
m_section->XSource.setValues(m_xShapes);
}
Gui::Command::commitCommand();
if (m_section) {
m_section->recomputeFeature();
}
void TaskComplexSection::updateComplexSection()
{
// Base::Console().Message("TCS:;updateComplexSection()\n");
if (!isSectionValid()) {
failNoObject();
return;
}
return;
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Edit SectionView"));
if (m_section) {
QString qTemp = ui->leSymbol->text();
std::string temp = Base::Tools::toStdString(qTemp);
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.SectionSymbol = '%s'",
m_sectionName.c_str(),
temp.c_str());
std::string lblText = "Section " +
temp +
" - " +
temp;
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.Label = '%s'",
m_sectionName.c_str(),
lblText.c_str());
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.Scale = %0.6f",
m_sectionName.c_str(),
ui->sbScale->value());
int scaleType = ui->cmbScaleType->currentIndex();
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.ScaleType = %d",
m_sectionName.c_str(), scaleType);
int projectionStrategy = ui->cmbStrategy->currentIndex();
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.ProjectionStrategy = %d",
m_sectionName.c_str(), projectionStrategy);
Command::doCommand(Command::Doc, "App.activeDocument().%s.SectionDirection = 'Aligned'",
m_sectionName.c_str());
m_section->CuttingToolWireObject.setValue(m_profileObject);
m_section->SectionDirection.setValue("Aligned");
if (m_baseView) {
if (!m_localUnit.IsEqual(m_saveNormal, EWTOLERANCE) &&
m_localUnit.Length() != 0.0) {
//if we have changed the view direction (and by extension the
//section normal, update the feature with the new value.
//m_localUnit should always be valid, but will cause an exception
//if it is null.
m_section->setCSFromBase(m_localUnit * -1.0);
}
m_section->Source.setValues(m_baseView->Source.getValues());
m_section->XSource.setValues(m_baseView->XSource.getValues());
} else {
//without a baseView, our choice of SectionNormal and XDirection may well be wrong
//if we have not changed the direction, we leave things as they are
if (!m_localUnit.IsEqual(m_saveNormal, EWTOLERANCE)) {
//just do our best.
m_section->setCSFromLocalUnit(m_localUnit * -1.0);
m_localUnit = m_saveNormal; //don't repeat this work next time through
}
m_section->Source.setValues(m_shapes);
m_section->XSource.setValues(m_xShapes);
}
}
Gui::Command::commitCommand();
}
void TaskComplexSection::saveButtons(QPushButton* btnOK,
QPushButton* btnCancel)
void TaskComplexSection::failNoObject(void)
{
m_btnOK = btnOK;
m_btnCancel = btnCancel;
QString qsectionName = Base::Tools::fromStdString(m_sectionName);
QString qbaseName = Base::Tools::fromStdString(m_saveBaseName);
QString msg = tr("Can not continue. Object * %1 or %2 not found.").arg(qsectionName, qbaseName);
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Operation Failed"), msg);
Gui::Control().closeDialog();
}
void TaskComplexSection::enableTaskButtons(bool button)
bool TaskComplexSection::isBaseValid()
{
m_btnOK->setEnabled(button);
m_btnCancel->setEnabled(button);
if (!m_baseView)
return false;
App::DocumentObject* baseObj = m_doc->getObject(m_saveBaseName.c_str());
if (!baseObj)
return false;
return true;
}
bool TaskComplexSection::isSectionValid()
{
if (!m_section)
return false;
App::DocumentObject* sectionObj = m_doc->getObject(m_sectionName.c_str());
if (!sectionObj)
return false;
return true;
}
//******************************************************************************
bool TaskComplexSection::accept()
{
Gui::Document* doc = Gui::Application::Instance->getDocument(m_page->getDocument());
if (!doc)
return false;
createComplexSection();
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
// Base::Console().Message("TCS::accept()\n");
apply(true);
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
return true;
}
bool TaskComplexSection::reject()
{
Gui::Document* doc = Gui::Application::Instance->getDocument(m_page->getDocument());
if (!doc)
if (!m_section) { //no section created, nothing to undo
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
return false;
}
//make sure any dangling objects are cleaned up
Gui::Command::doCommand(Gui::Command::Gui, "App.activeDocument().recompute()");
if (!isSectionValid()) { //section !exist. nothing to undo
if (isBaseValid()) {
m_baseView->requestPaint();
}
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
return false;
}
if (m_createMode) {
std::string SectionName = m_section->getNameInDocument();
Gui::Command::doCommand(Gui::Command::Gui,
"App.ActiveDocument.%s.removeView(App.ActiveDocument.%s)",
m_savePageName.c_str(), SectionName.c_str());
Gui::Command::doCommand(Gui::Command::Gui,
"App.ActiveDocument.removeObject('%s')",
SectionName.c_str());
} else {
restoreSectionState();
m_section->recomputeFeature();
m_section->requestPaint();
}
if (isBaseValid()) {
m_baseView->requestPaint();
}
Gui::Command::updateActive();
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
return false;
return false;}
void TaskComplexSection::changeEvent(QEvent* event)
{
if (event->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -320,6 +773,16 @@ TaskDlgComplexSection::TaskDlgComplexSection(TechDraw::DrawPage* page,
Content.push_back(taskbox);
}
TaskDlgComplexSection::TaskDlgComplexSection(TechDraw::DrawComplexSection* complexSection)
: TaskDialog()
{
widget = new TaskComplexSection(complexSection);
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/TechDraw_ComplexSection"),
widget->windowTitle(), true, nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}
TaskDlgComplexSection::~TaskDlgComplexSection()
{
}
@@ -329,22 +792,11 @@ void TaskDlgComplexSection::update()
// widget->updateTask();
}
void TaskDlgComplexSection::modifyStandardButtons(QDialogButtonBox* box)
{
QPushButton* btnOK = box->button(QDialogButtonBox::Ok);
QPushButton* btnCancel = box->button(QDialogButtonBox::Cancel);
widget->saveButtons(btnOK, btnCancel);
}
//==== calls from the TaskView ===============================================================
void TaskDlgComplexSection::open()
{
}
void TaskDlgComplexSection::clicked(int)
{
}
bool TaskDlgComplexSection::accept()
{
widget->accept();

View File

@@ -46,6 +46,9 @@ class DrawComplexSection;
namespace TechDrawGui
{
class CompassWidget;
class VectorEditWidget;
class Ui_TaskComplexSection;
class TaskComplexSection : public QWidget
@@ -59,40 +62,85 @@ public:
std::vector<App::DocumentObject*> xShapes,
App::DocumentObject* profileObject,
std::vector<std::string> profileSubs);
TaskComplexSection(TechDraw::DrawComplexSection* complexSection);
~TaskComplexSection() = default;
virtual bool accept();
virtual bool reject();
void saveButtons(QPushButton* btnOK,
QPushButton* btnCancel);
void enableTaskButtons(bool button);
public Q_SLOTS:
void onSectionObjectsUseSelectionClicked();
void onProfileObjectsUseSelectionClicked();
protected:
void changeEvent(QEvent *event) override;
void saveSectionState();
void restoreSectionState();
bool apply(bool forceUpdate = false);
void applyQuick(std::string dir);
void applyAligned(Base::Vector3d localUnit);
void setUiPrimary();
void setUiEdit();
void setUiCommon();
void checkAll(bool check);
void enableAll(bool enable);
void failNoObject();
bool isBaseValid();
bool isSectionValid();
void updateUi();
protected Q_SLOTS:
void onSectionObjectsUseSelectionClicked();
void onProfileObjectsUseSelectionClicked();
void onUpClicked();
void onDownClicked();
void onLeftClicked();
void onRightClicked();
void onIdentifierChanged();
void onScaleChanged();
void scaleTypeChanged(int index);
void liveUpdateClicked();
void updateNowClicked();
void slotChangeAngle(double newAngle);
void slotViewDirectionChanged(Base::Vector3d newDirection);
private:
void createComplexSection();
void updateComplexSection();
QString sourcesToString();
std::unique_ptr<Ui_TaskComplexSection> ui;
TechDraw::DrawPage* m_page;
App::Document* m_doc;
TechDraw::DrawViewPart* m_baseView;
TechDraw::DrawComplexSection* m_section;
std::vector<App::DocumentObject*> m_shapes;
std::vector<App::DocumentObject*> m_xShapes;
App::DocumentObject* m_profileObject;
std::vector<std::string> m_profileSubs;
std::string m_dirName;
std::string m_sectionName;
Base::Vector3d m_saveNormal;
Base::Vector3d m_saveXDir;
std::string m_saveBaseName;
std::string m_savePageName;
std::string m_saveSymbol;
std::string m_saveDirName;
Base::Vector3d m_saveDirection;
Base::Vector3d m_saveOrigin;
double m_saveScale;
int m_saveScaleType;
bool m_saved;
bool m_createMode;
Base::Vector3d m_normal;
QPushButton* m_btnOK;
QPushButton* m_btnCancel;
int m_applyDeferred;
Base::Vector3d m_localUnit;
CompassWidget* m_compass;
double m_angle;
VectorEditWidget* m_viewDirectionWidget;
};
@@ -107,13 +155,13 @@ public:
std::vector<App::DocumentObject*> xShapes,
App::DocumentObject* profileObject,
std::vector<std::string> profileSubs);
TaskDlgComplexSection(TechDraw::DrawComplexSection* page);
~TaskDlgComplexSection() override;
public:
/// is called the TaskView when the dialog is opened
void open() override;
/// is called by the framework if an button is clicked which has no accept or reject role
void clicked(int) override;
/// is called by the framework if the dialog is accepted (Ok)
bool accept() override;
/// is called by the framework if the dialog is rejected (Cancel)
@@ -123,8 +171,6 @@ public:
{ return false; }
void update();
void modifyStandardButtons(QDialogButtonBox* box) override;
protected:
private:

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>370</width>
<height>478</height>
<height>612</height>
</rect>
</property>
<property name="sizePolicy">
@@ -85,6 +85,13 @@
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
@@ -93,14 +100,7 @@
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1,1">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Identifier</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QComboBox" name="cmbScaleType">
<property name="minimumSize">
<size>
@@ -128,8 +128,22 @@
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="dsbScale">
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Scale</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Scale Type</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="sbScale">
<property name="minimumSize">
<size>
<width>0</width>
@@ -141,41 +155,14 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Scale Type</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Scale</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="leSymbol">
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="toolTip">
<string>Identifier for this section</string>
</property>
</widget>
</item>
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Projection Strategy</string>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QComboBox" name="cmbStrategy">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -196,19 +183,19 @@
</size>
</property>
<property name="currentText">
<string>Single</string>
<string>Offset</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Single</string>
<string>Offset</string>
</property>
</item>
<item>
<property name="text">
<string>Piecewise</string>
<string>Aligned</string>
</property>
</item>
<item>
@@ -218,67 +205,194 @@
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Identifier</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="leSymbol">
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="toolTip">
<string>Identifier for this section</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>BaseView</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="leBaseView">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gbOrientation">
<property name="title">
<string>Section Normal</string>
<string>Set View Direction</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="viewDirectionLayout"/>
</item>
<item>
<layout class="QHBoxLayout" name="quickPickLayout">
<item>
<widget class="QPushButton" name="pbUp">
<property name="toolTip">
<string>Preset view direction looking up.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/actions/section-up.svg</normalon>
</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbDown">
<property name="toolTip">
<string>Preset view direction looking down.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/actions/section-down.svg</normalon>
</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbLeft">
<property name="toolTip">
<string>Preset view direction looking left.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/actions/section-left.svg</normalon>
</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbRight">
<property name="toolTip">
<string>Preset view direction looking right.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/actions/section-right.svg</normalon>
</iconset>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="compassLayout"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Preview</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Z</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>X</string>
<widget class="QCheckBox" name="cbLiveUpdate">
<property name="toolTip">
<string>Check to update display after every property change.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Y</string>
<string>Live Update</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="dsbXNormal">
<property name="minimum">
<double>-2147483647.000000000000000</double>
<widget class="QPushButton" name="pbUpdateNow">
<property name="toolTip">
<string>Rebuild display now. May be slow for complex models.</string>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
<property name="text">
<string>Update Now</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="dsbYNormal">
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="dsbZNormal">
<property name="minimum">
<double>-2147483647.000000000000000</double>
</property>
<property name="maximum">
<double>2147483647.000000000000000</double>
<item row="1" column="0">
<widget class="QLabel" name="lPendingUpdates">
<property name="text">
<string/>
</property>
</widget>
</item>

View File

@@ -30,7 +30,6 @@
#include <QMessageBox>
#endif // #ifndef _PreComp_
#include <Base/Console.h>
#include <Base/Tools.h>
#include <Base/UnitsApi.h>
@@ -58,7 +57,8 @@
//#include "ViewProviderViewPart.h"
#include <Mod/TechDraw/Gui/ui_TaskSectionView.h>
#include "Widgets/CompassWidget.h"
#include "Widgets/VectorEditWidget.h"
#include "TaskSectionView.h"
using namespace Gui;
@@ -71,10 +71,11 @@ TaskSectionView::TaskSectionView(TechDraw::DrawViewPart* base) :
m_base(base),
m_section(nullptr),
m_saveScale(1.0),
m_dirName(""),
m_doc(nullptr),
m_createMode(true),
m_saved(false),
m_abort(false)
m_applyDeferred(0)
{
//existence of base is guaranteed by CmdTechDrawSectionView (Command.cpp)
@@ -85,15 +86,12 @@ TaskSectionView::TaskSectionView(TechDraw::DrawViewPart* base) :
m_savePageName = m_base->findParentPage()->getNameInDocument();
ui->setupUi(this);
connect(ui->pbUp, SIGNAL(clicked(bool)), this, SLOT(onUpClicked()));
connect(ui->pbDown, SIGNAL(clicked(bool)), this, SLOT(onDownClicked()));
connect(ui->pbRight, SIGNAL(clicked(bool)), this, SLOT(onRightClicked()));
connect(ui->pbLeft, SIGNAL(clicked(bool)), this, SLOT(onLeftClicked()));
setUiPrimary();
}
m_applyDeferred = 0; //setting the direction widgets causes an increment of the deferred count,
//so we reset the counter and the message.
ui->lPendingUpdates->setText(QString());
}
//ctor for edit
TaskSectionView::TaskSectionView(TechDraw::DrawViewSection* section) :
@@ -104,7 +102,7 @@ TaskSectionView::TaskSectionView(TechDraw::DrawViewSection* section) :
m_doc(nullptr),
m_createMode(false),
m_saved(false),
m_abort(false)
m_applyDeferred(0)
{
//existence of section is guaranteed by ViewProviderViewSection.setEdit
@@ -112,76 +110,82 @@ TaskSectionView::TaskSectionView(TechDraw::DrawViewSection* section) :
m_sectionName = m_section->getNameInDocument();
App::DocumentObject* newObj = m_section->BaseView.getValue();
m_base = dynamic_cast<TechDraw::DrawViewPart*>(newObj);
if (!newObj || !m_base)
if (!newObj || !m_base) {
throw Base::RuntimeError("TaskSectionView - BaseView not found");
}
m_saveBaseName = m_base->getNameInDocument();
m_savePageName = m_base->findParentPage()->getNameInDocument();
ui->setupUi(this);
connect(ui->pbUp, SIGNAL(clicked(bool)), this, SLOT(onUpClicked()));
connect(ui->pbDown, SIGNAL(clicked(bool)), this, SLOT(onDownClicked()));
connect(ui->pbRight, SIGNAL(clicked(bool)), this, SLOT(onRightClicked()));
connect(ui->pbLeft, SIGNAL(clicked(bool)), this, SLOT(onLeftClicked()));
m_dirName = m_section->SectionDirection.getValueAsString();
saveSectionState();
setUiEdit();
m_applyDeferred = 0; //setting the direction widgets causes an increment of the deferred count,
//so we reset the counter and the message.
ui->lPendingUpdates->setText(QString());
}
void TaskSectionView::setUiPrimary()
{
// Base::Console().Message("TSV::setUiPrimary()\n");
setWindowTitle(QObject::tr("Create Section View"));
std::string temp = m_base->getNameInDocument();
QString qTemp = Base::Tools::fromStdString(temp);
ui->leBaseView->setText(qTemp);
ui->sbScale->setValue(m_base->getScale());
ui->cmbScaleType->setCurrentIndex(m_base->ScaleType.getValue());
//Allow or prevent scale changing initially
if (m_base->ScaleType.isValue("Custom")) {
ui->sbScale->setEnabled(true);
}
else {
ui->sbScale->setEnabled(false);
}
Base::Vector3d origin = m_base->getOriginalCentroid();
ui->sbOrgX->setUnit(Base::Unit::Length);
ui->sbOrgX->setValue(origin.x);
ui->sbOrgY->setUnit(Base::Unit::Length);
ui->sbOrgY->setValue(origin.y);
ui->sbOrgZ->setUnit(Base::Unit::Length);
ui->sbOrgZ->setValue(origin.z);
setUiCommon(origin);
// before the user did not select an orientation,
// the section properties cannot be changed
this->setToolTip(QObject::tr("Select at first an orientation"));
enableAll(false);
connect(ui->leSymbol, SIGNAL(editingFinished()), this, SLOT(onIdentifierChanged()));
// the UI file uses keyboardTracking = false so that a recomputation
// will only be triggered when the arrow keys of the spinboxes are used
connect(ui->sbScale, SIGNAL(valueChanged(double)), this, SLOT(onScaleChanged()));
connect(ui->sbOrgX, SIGNAL(valueChanged(double)), this, SLOT(onXChanged()));
connect(ui->sbOrgY, SIGNAL(valueChanged(double)), this, SLOT(onYChanged()));
connect(ui->sbOrgZ, SIGNAL(valueChanged(double)), this, SLOT(onZChanged()));
connect(ui->cmbScaleType, SIGNAL(currentIndexChanged(int)), this, SLOT(scaleTypeChanged(int)));
m_viewDirectionWidget->setValue(Base::Vector3d(1.0, 0.0, 0.0));
}
void TaskSectionView::setUiEdit()
{
// Base::Console().Message("TSV::setUiEdit()\n");
setWindowTitle(QObject::tr("Edit Section View"));
std::string temp = m_section->SectionSymbol.getValue();
QString qTemp = Base::Tools::fromStdString(temp);
ui->leSymbol->setText(qTemp);
ui->sbScale->setValue(m_section->getScale());
ui->cmbScaleType->setCurrentIndex(m_section->ScaleType.getValue());
//Allow or prevent scale changing initially
if (m_section->ScaleType.isValue("Custom")) {
ui->sbScale->setEnabled(true);
}
else {
ui->sbScale->setEnabled(false);
}
Base::Vector3d origin = m_section->SectionOrigin.getValue();
setUiCommon(origin);
// convert section normal to view angle
Base::Vector3d sectionNormalVec = m_section->SectionNormal.getValue();
Base::Vector3d projectedViewDirection = m_base->projectPoint(sectionNormalVec, false);
double viewAngle = atan2(-projectedViewDirection.y,
-projectedViewDirection.x);
m_compass->setDialAngle(viewAngle * 180.0 / M_PI);
m_viewDirectionWidget->setValue(sectionNormalVec * -1.0);
}
void TaskSectionView::setUiCommon(Base::Vector3d origin)
{
std::string temp = m_base->getNameInDocument();
QString qTemp = Base::Tools::fromStdString(temp);
ui->leBaseView->setText(qTemp);
temp = m_section->SectionSymbol.getValue();
qTemp = Base::Tools::fromStdString(temp);
ui->leSymbol->setText(qTemp);
ui->sbScale->setValue(m_section->getScale());
ui->cmbScaleType->setCurrentIndex(m_section->ScaleType.getValue());
Base::Vector3d origin = m_section->SectionOrigin.getValue();
ui->sbOrgX->setUnit(Base::Unit::Length);
ui->sbOrgX->setValue(origin.x);
ui->sbOrgY->setUnit(Base::Unit::Length);
@@ -189,33 +193,58 @@ void TaskSectionView::setUiEdit()
ui->sbOrgZ->setUnit(Base::Unit::Length);
ui->sbOrgZ->setValue(origin.z);
enableAll(false);
connect(ui->leSymbol, SIGNAL(editingFinished()), this, SLOT(onIdentifierChanged()));
//TODO: use event filter instead of keyboard tracking to capture enter/return keys
// the UI file uses keyboardTracking = false so that a recomputation
// will only be triggered when the arrow keys of the spinboxes are used
//if this is not done, recomputes are triggered on each key press giving
//unaccceptable UX
connect(ui->sbScale, SIGNAL(valueChanged(double)), this, SLOT(onScaleChanged()));
connect(ui->sbOrgX, SIGNAL(valueChanged(double)), this, SLOT(onXChanged()));
connect(ui->sbOrgY, SIGNAL(valueChanged(double)), this, SLOT(onYChanged()));
connect(ui->sbOrgZ, SIGNAL(valueChanged(double)), this, SLOT(onZChanged()));
connect(ui->cmbScaleType, SIGNAL(currentIndexChanged(int)), this, SLOT(scaleTypeChanged(int)));
connect(ui->pbUp, SIGNAL(clicked(bool)), this, SLOT(onUpClicked()));
connect(ui->pbDown, SIGNAL(clicked(bool)), this, SLOT(onDownClicked()));
connect(ui->pbRight, SIGNAL(clicked(bool)), this, SLOT(onRightClicked()));
connect(ui->pbLeft, SIGNAL(clicked(bool)), this, SLOT(onLeftClicked()));
connect(ui->pbUpdateNow, SIGNAL(clicked(bool)), this, SLOT(updateNowClicked()));
connect(ui->cbLiveUpdate, SIGNAL(clicked(bool)), this, SLOT(liveUpdateClicked()));
m_compass = new CompassWidget(this);
auto layout = ui->compassLayout;
layout->addWidget(m_compass);
connect(m_compass, SIGNAL(angleChanged(double)), this, SLOT(slotChangeAngle(double)));
m_viewDirectionWidget = new VectorEditWidget(this);
m_viewDirectionWidget->setLabel(QObject::tr("Current View Direction"));
auto editLayout = ui->viewDirectionLayout;
editLayout->addWidget(m_viewDirectionWidget);
connect(m_viewDirectionWidget, SIGNAL(valueChanged(Base::Vector3d)),
this, SLOT(slotViewDirectionChanged(Base::Vector3d)));
}
//save the start conditions
void TaskSectionView::saveSectionState()
{
// Base::Console().Message("TSV::saveSectionState()\n");
if (!m_section)
return;
m_saveSymbol = m_section->SectionSymbol.getValue();
m_saveScale = m_section->getScale();
m_saveScaleType = m_section->ScaleType.getValue();
m_saveNormal = m_section->SectionNormal.getValue();
m_saveDirection = m_section->Direction.getValue();
m_saveOrigin = m_section->SectionOrigin.getValue();
m_saveDirName = m_section->SectionDirection.getValueAsString();
m_saved = true;
if (m_section) {
m_saveSymbol = m_section->SectionSymbol.getValue();
m_saveScale = m_section->getScale();
m_saveScaleType = m_section->ScaleType.getValue();
m_saveNormal = m_section->SectionNormal.getValue();
m_normal = m_saveNormal;
m_saveDirection = m_section->Direction.getValue();
m_saveOrigin = m_section->SectionOrigin.getValue();
m_saveDirName = m_section->SectionDirection.getValueAsString();
m_saved = true;
}
}
//restore the start conditions
@@ -234,36 +263,72 @@ void TaskSectionView::restoreSectionState()
m_section->SectionDirection.setValue(m_saveDirName.c_str());
}
//the VectorEditWidget reports a change in direction
void TaskSectionView::slotViewDirectionChanged(Base::Vector3d newDirection)
{
// Base::Console().Message("TSV::slotViewDirectionChanged(%s)\n",
// DrawUtil::formatVector(newDirection).c_str());
Base::Vector3d projectedViewDirection = m_base->projectPoint(newDirection, false);
projectedViewDirection.Normalize();
double viewAngle = atan2(projectedViewDirection.y,
projectedViewDirection.x);
m_compass->setDialAngle(viewAngle * 180.0 / M_PI);
checkAll(false);
applyAligned(projectedViewDirection);
}
//the CompassWidget reports that the view direction angle has changed
void TaskSectionView::slotChangeAngle(double newAngle)
{
// Base::Console().Message("TSV::slotChangeAngle(%.3f)\n", newAngle);
double angleRadians = newAngle * M_PI / 180.0;
double unitX = cos(angleRadians);
double unitY = sin(angleRadians);
Base::Vector3d localUnit(unitX, unitY, 0.0);
m_viewDirectionWidget->setValueNoNotify(localUnit);
checkAll(false);
applyAligned(localUnit);
}
//preset view directions
void TaskSectionView::onUpClicked()
{
// Base::Console().Message("TSV::onUpClicked()\n");
m_compass->setToNorth();
Base::Vector3d localUnit(0.0, 1.0, 0.0);
m_viewDirectionWidget->setValue(localUnit);
checkAll(false);
ui->pbUp->setChecked(true);
applyQuick("Up");
applyAligned(localUnit);
}
void TaskSectionView::onDownClicked()
{
// Base::Console().Message("TSV::onDownClicked()\n");
m_compass->setToSouth();
Base::Vector3d localUnit(0.0, -1.0, 0.0);
m_viewDirectionWidget->setValue(localUnit);
checkAll(false);
ui->pbDown->setChecked(true);
applyQuick("Down");
applyAligned(localUnit);
}
void TaskSectionView::onLeftClicked()
{
// Base::Console().Message("TSV::onLeftClicked()\n");
m_compass->setToWest();
Base::Vector3d localUnit(-1.0, 0.0, 0.0);
m_viewDirectionWidget->setValue(localUnit);
checkAll(false);
ui->pbLeft->setChecked(true);
applyQuick("Left");
applyAligned(localUnit);
}
void TaskSectionView::onRightClicked()
{
// Base::Console().Message("TSV::onRightClicked()\n");
m_compass->setToEast();
Base::Vector3d localUnit(1.0, 0.0, 0.0);
m_viewDirectionWidget->setValue(localUnit);
checkAll(false);
ui->pbRight->setChecked(true);
applyQuick("Right");
applyAligned(localUnit);
}
void TaskSectionView::onIdentifierChanged()
@@ -278,18 +343,17 @@ void TaskSectionView::onScaleChanged()
apply();
}
//SectionOrigin changed
void TaskSectionView::onXChanged()
{
checkAll(false);
apply();
}
void TaskSectionView::onYChanged()
{
checkAll(false);
apply();
}
void TaskSectionView::onZChanged()
{
checkAll(false);
@@ -303,6 +367,7 @@ void TaskSectionView::scaleTypeChanged(int index)
ui->sbScale->setEnabled(false);
if (m_base->findParentPage()) {
ui->sbScale->setValue(m_base->findParentPage()->Scale.getValue());
ui->sbScale->setEnabled(false);
}
} else if (index == 1) {
// Automatic Scale Type
@@ -315,6 +380,7 @@ void TaskSectionView::scaleTypeChanged(int index)
ui->sbScale->setEnabled(true);
if (m_section) {
ui->sbScale->setValue(m_section->Scale.getValue());
ui->sbScale->setEnabled(true);
}
} else {
Base::Console().Log("Error - TaskSectionView::scaleTypeChanged - unknown scale type: %d\n", index);
@@ -338,25 +404,68 @@ void TaskSectionView::enableAll(bool enable)
ui->sbOrgY->setEnabled(enable);
ui->sbOrgZ->setEnabled(enable);
ui->cmbScaleType->setEnabled(enable);
QString qScaleType = ui->cmbScaleType->currentText();
//Allow or prevent scale changing initially
if (qScaleType == QString::fromUtf8("Custom")) {
ui->sbScale->setEnabled(true);
}
else {
ui->sbScale->setEnabled(false);
}
}
void TaskSectionView::liveUpdateClicked() {
apply(true);
}
void TaskSectionView::updateNowClicked() {
apply(true);
}
//******************************************************************************
bool TaskSectionView::apply()
bool TaskSectionView::apply(bool forceUpdate)
{
// Base::Console().Message("TSV::apply() - m_dirName: %s\n", m_dirName.c_str());
// Base::Console().Message("TSV::apply() - liveUpdate: %d force: %d deferred: %d\n",
// ui->cbLiveUpdate->isChecked(), forceUpdate, m_applyDeferred);
if(!ui->cbLiveUpdate->isChecked() &&
!forceUpdate) {
//nothing to do
m_applyDeferred++;
QString msgLiteral = QString::fromUtf8(QT_TRANSLATE_NOOP("TaskPojGroup", " updates pending"));
QString msgNumber = QString::number(m_applyDeferred);
ui->lPendingUpdates->setText(msgNumber + msgLiteral);
return false;
}
Gui::WaitCursor wc;
if (m_dirName.empty()) {
std::string msg =
//this should never happen
std::string msg =
Base::Tools::toStdString(tr("Nothing to apply. No section direction picked yet"));
Base::Console().Error((msg + "\n").c_str());
return false;
}
if (!m_section) //didn't create the feature yet
//this can't happen as applyQuick has to be called by the direction
//setting process
return false;
if (!m_section) {
m_section = createSectionView();
}
if (isSectionValid()) {
updateSectionView();
} else {
failNoObject();
}
m_section->recomputeFeature();
if (isBaseValid()) {
m_base->requestPaint();
}
enableAll(true);
checkAll(false);
applyQuick(m_dirName);
wc.restoreCursor();
m_applyDeferred = 0;
ui->lPendingUpdates->setText(QString());
return true;
}
@@ -364,39 +473,27 @@ void TaskSectionView::applyQuick(std::string dir)
{
// Base::Console().Message("TSV::applyQuick(%s)\n", dir.c_str());
m_dirName = dir;
if (!m_section)
createSectionView();
if (!isSectionValid()) {
failNoObject(m_sectionName);
return;
}
updateSectionView();
enableAll(true);
m_section->recomputeFeature();
if (isBaseValid())
m_base->requestPaint();
apply();
}
void TaskSectionView::applyAligned()
void TaskSectionView::applyAligned(Base::Vector3d localUnit)
{
Base::Console().Message("TSV::applyAligned() - not implemented yet\n");
// Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Apply Aligned"));
// Base::Console().Message("TSV::applyAligned()\n");
m_dirName = "Aligned";
//fiddle with directions here
m_localUnit = localUnit;
enableAll(true);
apply();
}
//*********************************************************************
//pointer to created view is not returned, but stored in m_section
void TaskSectionView::createSectionView()
TechDraw::DrawViewSection* TaskSectionView::createSectionView(void)
{
// Base::Console().Message("TSV::createSectionView()\n");
if (!isBaseValid()) {
failNoObject(m_baseName);
return;
failNoObject();
return nullptr;
}
std::string sectionName;
@@ -416,7 +513,7 @@ void TaskSectionView::createSectionView()
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.Source = App.ActiveDocument.%s.Source",
m_sectionName.c_str(), baseName.c_str());
Command::doCommand(Command::Doc,
"App.ActiveDocument.%s.SectionOrigin = FreeCAD.Vector(%.3f, %.3f, %.3f)",
"App.ActiveDocument.%s.SectionOrigin = FreeCAD.Vector(%.6f, %.6f, %.6f)",
m_sectionName.c_str(),
ui->sbOrgX->value().getValue(),
ui->sbOrgY->value().getValue(),
@@ -427,22 +524,32 @@ void TaskSectionView::createSectionView()
int scaleType = ui->cmbScaleType->currentIndex();
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.ScaleType = %d",
m_sectionName.c_str(), scaleType);
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.SectionDirection = '%s'",
m_sectionName.c_str(), m_dirName.c_str());
App::DocumentObject* newObj = m_base->getDocument()->getObject(m_sectionName.c_str());
m_section = dynamic_cast<TechDraw::DrawViewSection*>(newObj);
if (!newObj || !m_section)
if (!newObj || !m_section) {
throw Base::RuntimeError("TaskSectionView - new section object not found");
}
if (m_dirName == "Aligned") {
//m_localUnit is a view direction so we need to reverse it to make a
//section normal
m_section->setCSFromBase(m_localUnit * -1.0);
} else {
//Note: DirectionName is to be deprecated in the future
m_section->setCSFromBase(m_dirName.c_str());
}
}
Gui::Command::commitCommand();
return;
return m_section;
}
void TaskSectionView::updateSectionView()
{
// Base::Console().Message("TSV::updateSectionView() - m_sectionName: %s\n", m_sectionName.c_str());
if (!isSectionValid()) {
failNoObject(m_sectionName);
failNoObject();
return;
}
@@ -474,18 +581,28 @@ void TaskSectionView::updateSectionView()
int scaleType = ui->cmbScaleType->currentIndex();
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.ScaleType = %d",
m_sectionName.c_str(), scaleType);
m_section->setCSFromBase(m_dirName.c_str());
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.SectionDirection = '%s'",
m_sectionName.c_str(), m_dirName.c_str());
if (m_dirName == "Aligned") {
//m_localUnit is a view direction so we need to reverse it to make a
//section normal
m_section->setCSFromBase(m_localUnit * -1.0);
} else {
//Note: DirectionName is to be deprecated in the future
m_section->setCSFromBase(m_dirName.c_str());
}
}
Gui::Command::commitCommand();
}
void TaskSectionView::failNoObject(std::string objectName)
void TaskSectionView::failNoObject(void)
{
QString qObjectName = Base::Tools::fromStdString(objectName);
QString msg = tr("Can not continue. Object * %1 * not found.").arg(qObjectName);
QString qsectionName = Base::Tools::fromStdString(m_sectionName);
QString qbaseName = Base::Tools::fromStdString(m_baseName);
QString msg = tr("Can not continue. Object * %1 or %2 not found.").arg(qsectionName, qbaseName);
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Operation Failed"), msg);
Gui::Control().closeDialog();
m_abort = true;
}
bool TaskSectionView::isBaseValid()
@@ -517,12 +634,8 @@ bool TaskSectionView::isSectionValid()
bool TaskSectionView::accept()
{
// Base::Console().Message("TSV::accept()\n");
if (m_abort) {
return true;
}
apply();
Gui::Command::updateActive();
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
apply(true);
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
return true;
}
@@ -589,6 +702,7 @@ TaskDlgSectionView::TaskDlgSectionView(TechDraw::DrawViewSection* section) :
widget = new TaskSectionView(section);
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("actions/TechDraw_SectionView"),
widget->windowTitle(), true, nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}

View File

@@ -39,6 +39,9 @@ namespace TechDraw {
namespace TechDrawGui
{
class CompassWidget;
class VectorEditWidget;
class TaskSectionView : public QWidget
{
Q_OBJECT
@@ -56,20 +59,21 @@ protected:
void saveSectionState();
void restoreSectionState();
bool apply();
bool apply(bool forceUpdate = false);
void applyQuick(std::string dir);
void applyAligned();
void applyAligned(Base::Vector3d localUnit);
void createSectionView();
TechDraw::DrawViewSection* createSectionView();
void updateSectionView();
void setUiPrimary();
void setUiEdit();
void setUiCommon(Base::Vector3d origin);
void checkAll(bool check);
void enableAll(bool enable);
void failNoObject(std::string objectName);
void failNoObject();
bool isBaseValid();
bool isSectionValid();
@@ -84,6 +88,10 @@ protected Q_SLOTS:
void onYChanged();
void onZChanged();
void scaleTypeChanged(int index);
void liveUpdateClicked();
void updateNowClicked();
void slotChangeAngle(double newAngle);
void slotViewDirectionChanged(Base::Vector3d newDirection);
private:
std::unique_ptr<Ui_TaskSectionView> ui;
@@ -113,8 +121,10 @@ private:
std::string m_saveBaseName;
std::string m_savePageName;
bool m_abort;
int m_applyDeferred;
Base::Vector3d m_localUnit;
CompassWidget* m_compass;
VectorEditWidget* m_viewDirectionWidget;
};
class TaskDlgSectionView : public Gui::TaskView::TaskDialog

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>370</width>
<height>368</height>
<height>508</height>
</rect>
</property>
<property name="sizePolicy">
@@ -82,7 +82,7 @@
</property>
</widget>
</item>
<item row="2" column="2">
<item row="2" column="2">
<widget class="QComboBox" name="cmbScaleType">
<property name="minimumSize">
<size>
@@ -140,6 +140,9 @@
<property name="toolTip">
<string>Scale factor for the section view</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
@@ -157,7 +160,7 @@
</property>
</widget>
</item>
</layout>
</layout>
</item>
<item>
<widget class="Line" name="line">
@@ -167,11 +170,14 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<widget class="QGroupBox" name="gbOrientation">
<property name="title">
<string>Section Orientation</string>
<string>Set View Direction</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="viewDirectionLayout"/>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
@@ -183,7 +189,7 @@
</size>
</property>
<property name="toolTip">
<string>Looking up</string>
<string>Preset view direction looking up.</string>
</property>
<property name="statusTip">
<string/>
@@ -219,7 +225,7 @@
</size>
</property>
<property name="toolTip">
<string>Looking down</string>
<string>Preset view direction looking down.</string>
</property>
<property name="text">
<string/>
@@ -249,7 +255,7 @@
</size>
</property>
<property name="toolTip">
<string>Looking left</string>
<string>Preset view direction looking left.</string>
</property>
<property name="text">
<string/>
@@ -279,7 +285,7 @@
</size>
</property>
<property name="toolTip">
<string>Looking right</string>
<string>Preset view direction looking right.</string>
</property>
<property name="text">
<string/>
@@ -302,6 +308,9 @@
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="compassLayout"/>
</item>
</layout>
</widget>
</item>
@@ -313,14 +322,14 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<widget class="QGroupBox" name="gbPlane">
<property name="toolTip">
<string>Position from the 3D origin of the object in the view</string>
</property>
<property name="title">
<string>Section Plane Location</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayoutPlane">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
@@ -369,6 +378,9 @@
<height>22</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
@@ -410,6 +422,9 @@
<height>22</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
@@ -451,6 +466,9 @@
<height>22</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
@@ -464,6 +482,56 @@
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gbUpdate">
<property name="title">
<string>Preview</string>
</property>
<layout class="QVBoxLayout" name="verticalLayoutUpdate">
<item>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="1">
<widget class="QPushButton" name="pbUpdateNow">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Rebuild display now. May be slow for complex models.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Update Now</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="cbLiveUpdate">
<property name="toolTip">
<string>Check to update display after every property change.</string>
</property>
<property name="text">
<string>Live Update</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lPendingUpdates">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
@@ -474,7 +542,7 @@
</customwidget>
</customwidgets>
<resources>
<include location="Resources/TechDraw.qrc"/>
<include location="../../../../../../Documents/FreeCAD/Stash/Gui_SectionDlg/Resources/TechDraw.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -36,10 +36,12 @@
#include <Gui/Control.h>
#include <Gui/Selection.h>
#include <Mod/TechDraw/App/DrawComplexSection.h>
#include <Mod/TechDraw/App/DrawGeomHatch.h>
#include <Mod/TechDraw/App/DrawHatch.h>
#include "TaskSectionView.h"
#include "TaskComplexSection.h"
#include "ViewProviderViewSection.h"
#include "QGIView.h"
@@ -123,6 +125,12 @@ bool ViewProviderViewSection::setEdit(int ModNum)
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
auto dcs = dynamic_cast<TechDraw::DrawComplexSection*>(getViewObject());
if (dcs) {
Gui::Control().showDialog(new TaskDlgComplexSection(dcs));
return true;
}
Gui::Control().showDialog(new TaskDlgSectionView(getViewObject()));
return true;
}
@@ -133,7 +141,6 @@ bool ViewProviderViewSection::doubleClicked()
return true;
}
void ViewProviderViewSection::getParameters()
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()

View File

@@ -0,0 +1,242 @@
/***************************************************************************
* 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 *
* *
***************************************************************************/
//largely based on a python widget from:
//https://github.com/tcalmant/demo-ipopo-qt/blob/master/pc/details/compass.py
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <QtGui>
#include <Base/Console.h>
#include <Base/Tools.h>
#include "CompassDialWidget.h"
using namespace TechDrawGui;
using CardinalMap = std::map<int, std::string>;
CompassDialWidget::CompassDialWidget(QWidget* parent) : QWidget(parent),
m_markInterval(15),
m_defaultSize(75),
m_defaultMargin(10),
m_designRadius(64)
{
setObjectName(QString::fromUtf8("Compass"));
m_rect = QRect(0, 0, m_defaultSize, m_defaultSize);
m_angle = 0.0;
m_margin = m_defaultMargin;
m_designDiameter = 2 * m_designRadius;
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
sizePolicy.setHorizontalStretch(1);
sizePolicy.setVerticalStretch(1);
setSizePolicy(sizePolicy);
repaint();
}
QSize CompassDialWidget::sizeHint() const
{
return m_rect.size();
}
QSize CompassDialWidget::minimumSizeHint() const
{
return QRect(0, 0, m_defaultSize, m_defaultSize).size();
}
void CompassDialWidget::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event);
QPainter painter(this);
drawWidget(painter);
QWidget::paintEvent(event);
}
void CompassDialWidget::drawWidget(QPainter& painter)
{
painter.setRenderHint(QPainter::Antialiasing, true);
// Draw the background
drawBackground(painter);
//Draw the cardinal points
drawMarkings(painter);
//Draw the needle
drawNeedle(painter);
}
void CompassDialWidget::drawBackground(QPainter& painter)
{
painter.save();
painter.setPen(QPen(Qt::NoPen));
// Clear the background
painter.fillRect(m_rect, palette().brush((QPalette::Window)));
painter.restore();
}
//Draws the cardinal points on painter. This widget was designed such that
//the dial gradations extend to 50 units from center and the compass point text
//begins at 52 units from the center. With the font size set to 12 pixels, this
//gives a design area of a circle with a radius of approximately 64 units. All of
//the constants reflect this design size.
void CompassDialWidget::drawMarkings(QPainter& painter)
{
CardinalMap CompassPointText( { {0, "Y"}, {45, "XY"}, {90, "X"}, {135, "X-Y"}, {180, "-Y"},
{225, "-X-Y"}, {270, "-X"}, {315, "-XY"} } );
painter.save();
int markInterval(15);
//Move to the center of the compass
painter.translate(width() / 2, height() / 2);
double scale = std::min((float) width() / (float) (m_designDiameter + 2.0 * m_margin),
(float) height() / (float) (m_designDiameter + 2.0 * m_margin));
painter.scale(scale, scale);
// Setup the fonts and the painter
QFont widgetFont = font();
widgetFont.setPixelSize(12);
QFontMetrics metrics(widgetFont);
//outer circle
int circleWidth = 2.0 * (m_designRadius + m_margin);
int circleHeight = 2.0 * (m_designRadius + m_margin);
QRect circleRect(-circleWidth / 2, -circleHeight / 2, circleWidth, circleHeight);
painter.drawEllipse(circleRect);
painter.setFont(widgetFont);
painter.setPen(QPen(palette().color(QPalette::WindowText)));
int iDegree = 0;
while ( iDegree < 360 ) {
if (iDegree % 45 == 0) {
//Named direction (every 45°)
painter.drawLine(0, -40, 0, -50); //this has to depend on m_rect or size?
QString qPointText = Base::Tools::fromStdString(CompassPointText.at(iDegree));
painter.drawText(-metrics.boundingRect(qPointText).width() / 2.0, -52, qPointText);
// what is -52? line end point y = -50 + 2 for margin?
} else {
//Small line
painter.drawLine(0, -45, 0, -50);
}
//Next line (+15°)
painter.rotate(markInterval);
iDegree += markInterval;
}
painter.restore();
}
//Draws a needle on painter
void CompassDialWidget::drawNeedle(QPainter& painter)
{
painter.save();
//Move to the center of the compass
painter.translate(width() / 2, height() / 2);
//Rotate to the correct angle
painter.rotate(m_angle);
double scale = std::min((float) width() / (float) (m_designDiameter + 2.0 * m_margin),
(float) height() / (float) (m_designDiameter + 2.0 * m_margin));
painter.scale(scale, scale);
//Setup the painter
QPen needlePen(palette().color(QPalette::WindowText));
needlePen.setWidth(2);
needlePen.setStyle(Qt::DashDotLine);
painter.setPen(needlePen);
painter.setBrush(palette().color(QPalette::WindowText));
//Draw the section line
int sectionLineExtent(25);
painter.drawLine(0, sectionLineExtent, 0, -sectionLineExtent);
needlePen.setStyle(Qt::SolidLine);
painter.setPen(needlePen);
int viewDirectionExtent(15);
painter.drawLine(-viewDirectionExtent, sectionLineExtent, 0, sectionLineExtent);
painter.drawLine(-viewDirectionExtent, -sectionLineExtent, 0, -sectionLineExtent);
//Draw the arrowheads of the needle section line
needlePen.setWidth(1);
needlePen.setStyle(Qt::SolidLine);
painter.setPen(needlePen);
int arrowLength(5);
int arrowWidth(3); //actual 1/2 width
painter.drawPolygon(
QPolygon( { QPoint(0, sectionLineExtent),
QPoint(-arrowLength, sectionLineExtent + arrowWidth),
QPoint(-arrowLength, sectionLineExtent - arrowWidth),
QPoint(0, sectionLineExtent) } ) );
painter.drawPolygon(
QPolygon( { QPoint(0, -sectionLineExtent),
QPoint(-arrowLength, -(sectionLineExtent + arrowWidth)),
QPoint(-arrowLength, -(sectionLineExtent - arrowWidth)),
QPoint(0, -sectionLineExtent) } ) );
//draw the actual needle
needlePen.setStyle(Qt::SolidLine);
painter.setPen(needlePen);
painter.setBrush(palette().color(QPalette::BrightText));
int needleExtent(40);
painter.drawPolygon(
QPolygon( { QPoint(needleExtent, 0),
QPoint(0, 5),
QPoint(-15, 2),
QPoint(-15, -2),
QPoint(0, -5),
QPoint(needleExtent, 0) } ) );
//draw needle pivot
painter.setBrush(palette().color(QPalette::WindowText));
int pivotSize(4);
QRect pivotRect(-pivotSize / 2, -pivotSize / 2, pivotSize, pivotSize);
painter.drawEllipse(pivotRect);
//draw needle point
painter.setBrush(QBrush(Qt::red));
int pointLength(5);
int pointWidth(3);
painter.drawPolygon(
QPolygon( { QPoint(needleExtent, 0),
QPoint(needleExtent - pointLength, pointWidth),
QPoint(needleExtent - pointLength, -pointWidth),
QPoint(needleExtent, 0) } ) );
painter.restore();
}
//convert a conventional angle to a Qt angle and set the dial accordingly
void CompassDialWidget::setAngle(double newAngle)
{
m_angle = fmod(360.0 - newAngle, 360.0);
repaint();
}
void CompassDialWidget::setSize(int newSize)
{
m_rect = QRect(0, 0, newSize, newSize);
repaint();
}

View File

@@ -0,0 +1,71 @@
/***************************************************************************
* 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 *
* *
***************************************************************************/
//based on a python widget from:
//https://github.com/tcalmant/demo-ipopo-qt/blob/master/pc/details/compass.py
#ifndef COMPASSDIALWIDGET_H
#define COMPASSDIALWIDGET_H
#include <QWidget>
#include <QSize>
namespace TechDrawGui {
class CompassDialWidget : public QWidget
{
Q_OBJECT
public:
CompassDialWidget(QWidget* parent = 0);
~CompassDialWidget() = default;
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
double angle() const { return m_angle; }
void setAngle(double newAngle);
void setSize(int newSize);
public Q_SLOTS:
void slotChangeAngle(double angle) { setAngle(angle); }
void resetAngle() { setAngle(0.0); }
protected:
void paintEvent(QPaintEvent* event) override;
void drawWidget(QPainter& painter);
void drawNeedle(QPainter& painter);
void drawMarkings(QPainter& painter);
void drawBackground(QPainter& painter);
private:
QRect m_rect;
double m_angle;
double m_margin;
double m_markInterval;
int m_defaultSize;
int m_defaultMargin;
int m_designRadius;
int m_designDiameter;
};
} //namespace TechDrawGui
#endif // COMPASSDIALWIDGET_H

View File

@@ -0,0 +1,254 @@
/***************************************************************************
* 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 *
* *
***************************************************************************/
// The CompassWidget has several children widgets - a CompassDialWidget, a fine
// adjustment QDoubleSpinBox and a QPushButton that acts as an enter key
// for the spin box.
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QApplication>
#include <QLabel>
#include <QObject>
#include <QPushButton>
#include <QtGui>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QVBoxLayout>
#endif
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <Base/Console.h>
#include <Base/Tools.h>
#include "CompassDialWidget.h"
#include "CompassWidget.h"
using namespace TechDrawGui;
CompassWidget::CompassWidget(QWidget *parent)
: QWidget(parent), m_minimumWidth(200), m_minimumHeight(200), m_defaultMargin(10), m_angle(0.0),
m_advanceIncrement(10.0)
{
setObjectName(QString::fromUtf8("Compass"));
m_rect = QRect(0, 0, m_minimumWidth, m_minimumHeight);
buildWidget();
compassDial->setSize(m_minimumHeight - 2 * m_defaultMargin);
connect(pbUseCompassSetting, &QPushButton::pressed, this, &CompassWidget::slotUseSpinboxValue);
dsbAngle->installEventFilter(this);
connect(pbCWAdvance, &QPushButton::pressed, this, &CompassWidget::slotCWAdvance);
connect(pbCCWAdvance, &QPushButton::pressed, this, &CompassWidget::slotCCWAdvance);
}
//trap Enter press in dsbAngle so as not to invoke task accept processing
bool CompassWidget::eventFilter(QObject *target, QEvent *event)
{
if (target == dsbAngle) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
dsbAngle->interpretText();
slotSpinBoxEnter(dsbAngle->value());
return true;
}
}
}
return QWidget::eventFilter(target, event);
}
void CompassWidget::buildWidget()
{
resize(m_minimumWidth, m_minimumHeight);
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(sizePolicy.hasHeightForWidth());
setSizePolicy(sizePolicy);
setMinimumSize(QSize(m_minimumWidth, m_minimumHeight));
compassLayout = new QVBoxLayout(this);
compassLayout->setObjectName(QString::fromUtf8("CompassLayout"));
compassDialLayout = new QHBoxLayout();
compassDialLayout->setObjectName(QString::fromUtf8("compassDialLayout"));
pbCWAdvance = new QPushButton(this);
pbCWAdvance->setObjectName(QString::fromUtf8("pbCWAdvance"));
QIcon icon1;
icon1.addFile(QString::fromUtf8(":/icons/arrow-cw.svg"), QSize(), QIcon::Normal, QIcon::On);
pbCWAdvance->setIcon(icon1);
compassDialLayout->addWidget(pbCWAdvance);
compassDial = new CompassDialWidget(this);
compassDial->setObjectName(QString::fromUtf8("CompassDial"));
compassDialLayout->addWidget(compassDial);
pbCCWAdvance = new QPushButton(this);
pbCCWAdvance->setObjectName(QString::fromUtf8("pbCCWAdvance"));
QIcon icon2;
icon2.addFile(QString::fromUtf8(":/icons/arrow-ccw.svg"), QSize(), QIcon::Normal, QIcon::On);
pbCCWAdvance->setIcon(icon2);
compassDialLayout->addWidget(pbCCWAdvance);
compassDialLayout->setStretch(1, 2);
compassLayout->addLayout(compassDialLayout);
compassControlLayout = new QHBoxLayout();
compassControlLayout->setObjectName(QString::fromUtf8("compassControlLayout"));
compassControlLabel = new QLabel(this);
compassControlLabel->setObjectName(QString::fromUtf8("compassControlLabel"));
QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Minimum);
sizePolicy2.setHorizontalStretch(0);
sizePolicy2.setVerticalStretch(0);
sizePolicy2.setHeightForWidth(compassControlLabel->sizePolicy().hasHeightForWidth());
compassControlLabel->setSizePolicy(sizePolicy2);
compassControlLayout->addWidget(compassControlLabel);
dsbAngle = new QDoubleSpinBox(this);
dsbAngle->setObjectName(QString::fromUtf8("dsbAngle"));
sizePolicy2.setHeightForWidth(dsbAngle->sizePolicy().hasHeightForWidth());
dsbAngle->setSizePolicy(sizePolicy2);
dsbAngle->setMinimumSize(QSize(75, 26));
dsbAngle->setMouseTracking(true);
dsbAngle->setFocusPolicy(Qt::ClickFocus);
dsbAngle->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
dsbAngle->setKeyboardTracking(false);
dsbAngle->setSuffix(QString::fromUtf8("\302\260"));
dsbAngle->setMaximum(360.000000000000000);
dsbAngle->setMinimum(-360.000000000000000);
compassControlLayout->addWidget(dsbAngle);
pbUseCompassSetting = new QPushButton(this);
pbUseCompassSetting->setObjectName(QString::fromUtf8("pbUseCompassSetting"));
QIcon icon;
icon.addFile(QString::fromUtf8(":/icons/edit_OK.svg"), QSize(), QIcon::Normal, QIcon::On);
pbUseCompassSetting->setIcon(icon);
pbUseCompassSetting->setText(QString());
compassControlLayout->addWidget(pbUseCompassSetting);
compassControlLayout->setStretch(0, 3);
compassControlLayout->setStretch(1, 2);
compassLayout->addLayout(compassControlLayout);
retranslateUi();
}
void CompassWidget::retranslateUi()
{
compassControlLabel->setText(
QApplication::translate("CompassWidget", "View Direction as Angle", nullptr));
#ifndef QT_NO_TOOLTIP
dsbAngle->setToolTip(QApplication::translate(
"CompassWidget", "The view direction angle relative to +X in the BaseView.", nullptr));
pbUseCompassSetting->setToolTip(QApplication::translate(
"CompassWidget", "Use the current view direction to set the Section Normal.", nullptr));
pbCWAdvance->setToolTip(QApplication::translate(
"CompassWidget", "Advance the view direction in clockwise direction.", nullptr));
pbCCWAdvance->setToolTip(QApplication::translate(
"CompassWidget", "Advance the view direction in anti-clockwise direction.", nullptr));
#endif// QT_NO_TOOLTIP
}
QSize CompassWidget::sizeHint() const { return m_rect.size(); }
QSize CompassWidget::minimumSizeHint() const
{
return QRect(0, 0, m_minimumWidth, m_minimumHeight).size();
}
void CompassWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QWidget::paintEvent(event);
}
//general purpose angle update from external source.
void CompassWidget::setDialAngle(double newAngle)
{
// Base::Console().Message("CW::setDialAngle(%.3f)\n", newAngle);
m_angle = newAngle;
if (compassDial) {
compassDial->setAngle(m_angle);
}
if (dsbAngle) {
dsbAngle->setValue(m_angle);
}
}
//slot for updates from spinbox arrows or typing.
void CompassWidget::slotSpinBoxUpdate(double newAngle)
{
// Base::Console().Message("CW::slotSpinBoxUpdate(%.3f)\n", newAngle);
m_angle = newAngle;
Q_EMIT angleChanged(m_angle);
if (compassDial) {
compassDial->setAngle(m_angle);
}
}
//slot for updates from spinbox on Enter/Return press.
void CompassWidget::slotSpinBoxEnter(double newAngle)
{
// Base::Console().Message("CW::slotSpinBoxEnter(%.3f)\n", newAngle);
if (dsbAngle) {
m_angle = newAngle;
Q_EMIT angleChanged(m_angle);
if (compassDial) {
compassDial->setAngle(m_angle);
}
}
}
//slot for OK button press
void CompassWidget::slotUseSpinboxValue()
{
// Base::Console().Message("CW::slotUseSpinboxValue()\n");
if (dsbAngle) {
dsbAngle->interpretText();
m_angle = dsbAngle->value();
Q_EMIT angleChanged(m_angle);
}
if (compassDial) {
compassDial->setAngle(m_angle);
}
}
void CompassWidget::slotCWAdvance()
{
double angle = m_angle - m_advanceIncrement;
if (angle < -360.0) {
angle = angle + 360.0;
}
setDialAngle(angle);
}
void CompassWidget::slotCCWAdvance()
{
double angle = m_angle + m_advanceIncrement;
setDialAngle(fmod(angle, 360.0));
}
void CompassWidget::setAdvanceIncrement(double newIncrement) { m_advanceIncrement = newIncrement; }

View File

@@ -0,0 +1,105 @@
/***************************************************************************
* 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 *
* *
***************************************************************************/
#ifndef COMPASSWIDGET_H
#define COMPASSWIDGET_H
#include <QDoubleSpinBox>
#include <QKeyEvent>
#include <QWidget>
#include <QSize>
QT_BEGIN_NAMESPACE
class QLabel;
class QHBoxLayout;
class QPushButton;
class QVBoxLayout;
QT_END_NAMESPACE
namespace TechDrawGui {
class CompassDialWidget;
class CompassWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY( double angle READ dialAngle WRITE setDialAngle NOTIFY angleChanged)
public:
CompassWidget(QWidget* parent = 0);
~CompassWidget() = default;
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
bool eventFilter(QObject *target, QEvent *event) override;
void retranslateUi();
double dialAngle() const { return m_angle; }
void setDialAngle(double newAngle);
void setAdvanceIncrement(double newIncrement);
double advanceIncrement() const { return m_advanceIncrement; }
Q_SIGNALS:
void angleChanged(double angle);
void angleSet(double angle);
public Q_SLOTS:
void slotChangeAngle(double angle) { setDialAngle(angle); }
void slotSpinBoxUpdate(double newAngle);
void slotSpinBoxEnter(double newAngle);
void slotUseSpinboxValue();
void resetAngle() { setDialAngle(0.0); } //conventional angles
void setToEast() { setDialAngle(0.0); }
void setToNorth() { setDialAngle(90.0); }
void setToWest() { setDialAngle(180.0); }
void setToSouth() { setDialAngle(270.0); }
void slotCWAdvance();
void slotCCWAdvance();
protected:
void paintEvent(QPaintEvent* event) override;
void buildWidget();
double changeAngleConvention(double CWY) const;
private:
QRect m_rect;
int m_minimumWidth;
int m_minimumHeight;
int m_defaultMargin;
double m_angle;
double m_advanceIncrement;
QVBoxLayout* compassLayout;
QHBoxLayout* compassDialLayout;
QHBoxLayout* compassControlLayout;
CompassDialWidget* compassDial;
// DoubleSpinBoxNoEnter* dsbAngle;
QDoubleSpinBox* dsbAngle;
QLabel* compassControlLabel;
QPushButton* pbUseCompassSetting;
QPushButton* pbCWAdvance;
QPushButton* pbCCWAdvance;
};
} //namespace TechDrawGui
#endif // COMPASSWIDGET_H

View File

@@ -0,0 +1,265 @@
/***************************************************************************
* 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 *
* *
***************************************************************************/
// A widget for editing Vector3d without taking up too much space in the UI.
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QApplication>
#include <QLabel>
#include <QObject>
#include <QPushButton>
#include <QtGui>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QSpacerItem>
#include <QToolButton>
#endif
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <limits>
#include <Base/Console.h>
#include <Base/Tools.h>
#include <Base/UnitsApi.h>
#include <Gui/SpinBox.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include "VectorEditWidget.h"
using namespace TechDrawGui;
using namespace TechDraw;
VectorEditWidget::VectorEditWidget(QWidget* parent) : QWidget(parent),
m_minimumWidth(200),
m_minimumHeight(30),
m_expandedHeight(155),
m_blockNotify(false)
{
m_size = QSize(m_minimumWidth, m_minimumHeight);
setObjectName(QString::fromUtf8("VectorEdit"));
buildWidget();
connect(tbExpand, SIGNAL(toggled(bool)), this, SLOT(slotExpandButtonToggled(bool)));
connect(dsbX, SIGNAL(valueChanged(double)), this, SLOT(xValueChanged(double)));
connect(dsbY, SIGNAL(valueChanged(double)), this, SLOT(yValueChanged(double)));
connect(dsbZ, SIGNAL(valueChanged(double)), this, SLOT(zValueChanged(double)));
dsbX->installEventFilter(this);
dsbY->installEventFilter(this);
dsbZ->installEventFilter(this);
}
//trap Enter press in dsb? so as not to invoke task accept processing
bool VectorEditWidget::eventFilter(QObject *target, QEvent *event)
{
if (target == dsbX ||
target == dsbY ||
target == dsbZ) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return ||
keyEvent->key() == Qt::Key_Enter) {
QDoubleSpinBox* dsb = static_cast<QDoubleSpinBox*>(target);
dsb->interpretText();
Q_EMIT dsb->valueChanged(dsb->value());
return true;
}
}
}
return QWidget::eventFilter(target, event);
}
void VectorEditWidget::setLabel(std::string newLabel)
{
QString qNewLabelString = Base::Tools::fromStdString(newLabel);
lvectorName->setText(qNewLabelString);
}
void VectorEditWidget::setLabel(QString newLabel)
{
lvectorName->setText(newLabel);
}
void VectorEditWidget::setValue(Base::Vector3d newValue)
{
// Base::Console().Message("VEW::setValue(%s)\n", DrawUtil::formatVector(newValue).c_str());
m_value = newValue;
dsbX->setValue(m_value.x);
dsbY->setValue(m_value.y);
dsbZ->setValue(m_value.z);
updateDisplay();
}
void VectorEditWidget::setValueNoNotify(Base::Vector3d newValue)
{
// Base::Console().Message("VEW::setValue(%s)\n", DrawUtil::formatVector(newValue).c_str());
m_value = newValue;
m_blockNotify = true;
dsbX->setValue(m_value.x);
dsbY->setValue(m_value.y);
dsbZ->setValue(m_value.z);
m_blockNotify = false;
updateDisplay();
}
void VectorEditWidget::slotExpandButtonToggled(bool checked)
{
// Base::Console().Message("VEW::slotExpand - checked: %d\n", checked);
if (checked) {
vectorEditLayout->addLayout(VectorEditItemLayout);
vectorEditLayout->addItem(verticalSpacer);
m_size = QSize(m_minimumWidth, m_expandedHeight);
} else {
vectorEditLayout->removeItem(VectorEditItemLayout);
vectorEditLayout->removeItem(verticalSpacer);
m_size = QSize(m_minimumWidth, m_minimumHeight);
}
}
void VectorEditWidget::xValueChanged(double newValue)
{
// Base::Console().Message("VEW::xValueChanged(%.3f)\n", newValue);
m_value.x = newValue;
updateDisplay();
if (!m_blockNotify) {
Q_EMIT valueChanged(m_value);
}
}
void VectorEditWidget::yValueChanged(double newValue)
{
// Base::Console().Message("VEW::yValueChanged(%.3f)\n", newValue);
m_value.y = newValue;
updateDisplay();
if (!m_blockNotify) {
Q_EMIT valueChanged(m_value);
}
}
void VectorEditWidget::zValueChanged(double newValue)
{
// Base::Console().Message("VEW::zValueChanged(%.3f)\n", newValue);
m_value.z = newValue;
updateDisplay();
if (!m_blockNotify) {
Q_EMIT valueChanged(m_value);
}
}
void VectorEditWidget::updateDisplay()
{
// Base::Console().Message("VEW::updateDisplay() - m_value: %s\n", DrawUtil::formatVector(m_value).c_str());
QString qNewDisplayString = Base::Tools::fromStdString(DrawUtil::formatVector(m_value));
leVectorDisplay->setText(qNewDisplayString);
}
QSize VectorEditWidget::minimumSizeHint() const
{
return m_size;
}
void VectorEditWidget::buildWidget()
{
if (objectName().isEmpty())
setObjectName(QString::fromUtf8("VectorEdit"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
setSizePolicy(sizePolicy);
vectorEditLayout = new QVBoxLayout(this);
vectorEditLayout->setObjectName(QString::fromUtf8("vectorEditLayout"));
vectorEditLayout->setContentsMargins(0, 0, 0, 0);
VectorEditButtonLayout = new QHBoxLayout();
VectorEditButtonLayout->setSpacing(0);
VectorEditButtonLayout->setObjectName(QString::fromUtf8("VectorEditButtonLayout"));
lvectorName = new QLabel(this);
lvectorName->setObjectName(QString::fromUtf8("lvectorName"));
VectorEditButtonLayout->addWidget(lvectorName);
leVectorDisplay = new QLineEdit(this);
leVectorDisplay->setObjectName(QString::fromUtf8("leVectorDisplay"));
VectorEditButtonLayout->addWidget(leVectorDisplay);
tbExpand = new QToolButton(this);
tbExpand->setObjectName(QString::fromUtf8("tbExpand"));
tbExpand->setText(QString::fromUtf8("..."));
tbExpand->setCheckable(true);
VectorEditButtonLayout->addWidget(tbExpand);
VectorEditButtonLayout->setStretch(0, 1);
VectorEditButtonLayout->setStretch(1, 1);
vectorEditLayout->addLayout(VectorEditButtonLayout);
VectorEditItemLayout = new QGridLayout();
VectorEditItemLayout->setObjectName(QString::fromUtf8("VectorEditItemLayout"));
lX = new QLabel();
lX->setObjectName(QString::fromUtf8("lX"));
lX->setText(QString::fromUtf8("X:"));
VectorEditItemLayout->addWidget(lX, 0, 0, 1, 1);
dsbX = new Gui::DoubleSpinBox();
dsbX->setObjectName(QString::fromUtf8("dsbX"));
dsbX->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
dsbX->setKeyboardTracking(false);
dsbX->setMaximum(std::numeric_limits<double>::max());
dsbX->setMinimum(std::numeric_limits<double>::lowest());
dsbX->setDecimals(Base::UnitsApi::getDecimals());
VectorEditItemLayout->addWidget(dsbX, 0, 1, 1, 1);
lY = new QLabel();
lY->setObjectName(QString::fromUtf8("lY"));
lY->setText(QString::fromUtf8("Y:"));
VectorEditItemLayout->addWidget(lY, 1, 0, 1, 1);
dsbY = new Gui::DoubleSpinBox();
dsbY->setObjectName(QString::fromUtf8("dsbY"));
dsbY->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
dsbY->setKeyboardTracking(false);
dsbY->setMaximum(std::numeric_limits<double>::max());
dsbY->setMinimum(std::numeric_limits<double>::lowest());
dsbY->setDecimals(Base::UnitsApi::getDecimals());
VectorEditItemLayout->addWidget(dsbY, 1, 1, 1, 1);
lZ = new QLabel();
lZ->setObjectName(QString::fromUtf8("lZ"));
lZ->setText(QString::fromUtf8("Z:"));
VectorEditItemLayout->addWidget(lZ, 2, 0, 1, 1);
dsbZ = new Gui::DoubleSpinBox();
dsbZ->setObjectName(QString::fromUtf8("dsbZ"));
dsbZ->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
dsbZ->setKeyboardTracking(false);
dsbZ->setMaximum(std::numeric_limits<double>::max());
dsbZ->setMinimum(std::numeric_limits<double>::lowest());
dsbZ->setDecimals(Base::UnitsApi::getDecimals());
VectorEditItemLayout->addWidget(dsbZ, 2, 1, 1, 1);
verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
}

View File

@@ -0,0 +1,107 @@
/***************************************************************************
* 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 *
* *
***************************************************************************/
#ifndef VECTOREDITWIDGET_H
#define VECTOREDITWIDGET_H
#include <QWidget>
#include <QSize>
#include <QString>
QT_BEGIN_NAMESPACE
class QVBoxLayout;
class QHBoxLayout;
class QGridLayout;
class QLabel;
class QLineEdit;
class QToolButton;
class QSpacerItem;
QT_END_NAMESPACE
namespace Gui {
class DoubleSpinBox;
}
#include <Base/Vector3D.h>
namespace TechDrawGui {
class VectorEditWidget : public QWidget
{
Q_OBJECT
public:
VectorEditWidget(QWidget* parent = 0);
~VectorEditWidget() = default;
QSize minimumSizeHint() const override;
bool eventFilter(QObject *target, QEvent *event) override;
void setLabel(std::string newLabel);
void setLabel(QString newLabel);
Base::Vector3d value() const { return m_value; }
Q_SIGNALS:
void valueChanged(Base::Vector3d newValue);
public Q_SLOTS:
void setValue(Base::Vector3d newValue);
void setValueNoNotify(Base::Vector3d newValue);
protected:
void buildWidget();
protected Q_SLOTS:
void slotExpandButtonToggled(bool checked);
void xValueChanged(double newValue);
void yValueChanged(double newValue);
void zValueChanged(double newValue);
void updateDisplay();
private:
int m_minimumWidth;
int m_minimumHeight;
int m_expandedHeight;
bool m_blockNotify;
QSize m_size;
Base::Vector3d m_value;
QVBoxLayout *vectorEditLayout;
QHBoxLayout *VectorEditButtonLayout;
QLabel *lvectorName;
QLineEdit *leVectorDisplay;
QToolButton *tbExpand;
QGridLayout *VectorEditItemLayout;
Gui::DoubleSpinBox *dsbX;
Gui::DoubleSpinBox *dsbY;
Gui::DoubleSpinBox *dsbZ;
QLabel *lX;
QLabel *lY;
QLabel *lZ;
QSpacerItem *verticalSpacer;
};
} //namespace TechDrawGui
#endif // VECTOREDITWIDGET_H

View File

@@ -246,8 +246,9 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
*views << "TechDraw_View";
*views << "TechDraw_ActiveView";
*views << "TechDraw_ProjectionGroup";
*views << "TechDraw_SectionView";
*views << "TechDraw_ComplexSection";
*views << "TechDraw_SectionGroup";
// *views << "TechDraw_SectionView";
// *views << "TechDraw_ComplexSection";
*views << "TechDraw_DetailView";
*views << "TechDraw_DraftView";
*views << "TechDraw_ArchView";
@@ -391,10 +392,10 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const
views->setCommand("Views");
*views << "TechDraw_View";
*views << "TechDraw_ActiveView";
// *views << "TechDraw_NewMulti"; //deprecated
*views << "TechDraw_ProjectionGroup";
*views << "TechDraw_SectionView";
*views << "TechDraw_ComplexSection";
*views << "TechDraw_SectionGroup";
// *views << "TechDraw_SectionView";
// *views << "TechDraw_ComplexSection";
*views << "TechDraw_DetailView";
*views << "TechDraw_DraftView";
*views << "TechDraw_SpreadsheetView";