"Professional CMake" book suggest the following: "Targets should build successfully with or without compiler support for precompiled headers. It should be considered an optimization, not a requirement. In particular, do not explicitly include a precompile header (e.g. stdafx.h) in the source code, let CMake force-include an automatically generated precompile header on the compiler command line instead. This is more portable across the major compilers and is likely to be easier to maintain. It will also avoid warnings being generated from certain code checking tools like iwyu (include what you use)." Therefore, removed the "#include <PreCompiled.h>" from sources, also there is no need for the "#ifdef _PreComp_" anymore
311 lines
11 KiB
C++
311 lines
11 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2022 WandererFan <wandererfan@gmail.com> *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <QMessageBox>
|
|
#include <QTableWidgetItem>
|
|
|
|
#include <App/Document.h>
|
|
#include <Gui/BitmapFactory.h>
|
|
#include <Gui/Command.h>
|
|
#include <Gui/MainWindow.h>
|
|
#include <Gui/Selection/Selection.h>
|
|
#include <Mod/TechDraw/App/DrawView.h>
|
|
#include <Mod/TechDraw/App/DrawViewPart.h>
|
|
|
|
#include "DimensionValidators.h"
|
|
#include "TaskDimRepair.h"
|
|
#include "ui_TaskDimRepair.h"
|
|
|
|
|
|
using namespace Gui;
|
|
using namespace TechDraw;
|
|
using namespace TechDrawGui;
|
|
|
|
TaskDimRepair::TaskDimRepair(TechDraw::DrawViewDimension* inDvd)
|
|
: ui(new Ui_TaskDimRepair),
|
|
m_dim(inDvd)
|
|
{
|
|
ui->setupUi(this);
|
|
|
|
connect(ui->pbSelection, &QPushButton::clicked, this, &TaskDimRepair::slotUseSelection);
|
|
|
|
saveDimState();
|
|
setUiPrimary();
|
|
}
|
|
|
|
TaskDimRepair::~TaskDimRepair()
|
|
{}
|
|
|
|
void TaskDimRepair::setUiPrimary()
|
|
{
|
|
setWindowTitle(QObject::tr("Dimension Repair"));
|
|
ui->leName->setReadOnly(true);
|
|
ui->leLabel->setReadOnly(true);
|
|
|
|
ui->leName->setText(QString::fromStdString(m_dim->getNameInDocument()));
|
|
ui->leLabel->setText(QString::fromStdString(m_dim->Label.getValue()));
|
|
|
|
DrawViewPart* viewPart = m_dim->getViewPart();
|
|
std::string objName = viewPart ? viewPart->getNameInDocument() : "";
|
|
std::string objLabel = viewPart ? viewPart->Label.getValue() : "";
|
|
ui->leObject2d->setText(QString::fromStdString(objName + " / " + objLabel));
|
|
const std::vector<std::string>& subElements2d = m_dim->References2D.getSubValues();
|
|
std::vector<std::string> labelsInOut(subElements2d.size());
|
|
fillList(ui->lwGeometry2d, labelsInOut, subElements2d);
|
|
|
|
QStringList headers;
|
|
headers << tr("Object name") << tr("Object label") << tr("Sub-element");
|
|
ui->twReferences3d->setHorizontalHeaderLabels(headers);
|
|
|
|
ReferenceVector references3d = m_dim->getReferences3d();
|
|
loadTableWidget(ui->twReferences3d, references3d);
|
|
}
|
|
|
|
void TaskDimRepair::saveDimState()
|
|
{
|
|
m_saveMeasureType = m_dim->MeasureType.getValue();
|
|
m_saveDimType = m_dim->Type.getValue();
|
|
m_saveRefs3d = m_dim->getReferences3d();
|
|
m_saveRefs2d = m_dim->getReferences2d();
|
|
m_saveDvp = m_dim->getViewPart();
|
|
}
|
|
|
|
//restore the start conditions
|
|
void TaskDimRepair::restoreDimState()
|
|
{
|
|
if (m_dim) {
|
|
m_dim->setReferences2d(m_saveRefs2d);
|
|
m_dim->setReferences3d(m_saveRefs3d);
|
|
}
|
|
}
|
|
|
|
//similar to code in CommandCreateDims.cpp
|
|
//use the current selection to replace the references in dim
|
|
void TaskDimRepair::slotUseSelection()
|
|
{
|
|
const std::vector<App::DocumentObject*> dimObjects =
|
|
Gui::Selection().getObjectsOfType(TechDraw::DrawViewDimension::getClassTypeId());
|
|
if (dimObjects.empty()) {
|
|
//selection does not include a dimension, so we need to add our dimension to keep the
|
|
//validators happy
|
|
//bool accepted =
|
|
static_cast<void>(Gui::Selection().addSelection(m_dim->getDocument()->getName(),
|
|
m_dim->getNameInDocument()));
|
|
}
|
|
ReferenceVector references2d;
|
|
ReferenceVector references3d;
|
|
TechDraw::DrawViewPart* dvp = TechDraw::getReferencesFromSelection(references2d, references3d);
|
|
if (dvp != m_saveDvp) {
|
|
int ret = QMessageBox::warning(Gui::getMainWindow(),
|
|
QObject::tr("Incorrect Selection?"),
|
|
QObject::tr("This will change the dimension's owner view. Continue?"),
|
|
QMessageBox::Cancel | QMessageBox::Ok);
|
|
if (ret == QMessageBox::Cancel) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
StringVector acceptableGeometry({ "Edge", "Vertex", "Face" });
|
|
std::vector<int> minimumCounts({1, 1, 1});
|
|
std::vector<DimensionGeometry> acceptableDimensionGeometrys;//accept anything
|
|
DimensionGeometry geometryRefs2d = validateDimSelection(
|
|
references2d, acceptableGeometry, minimumCounts, acceptableDimensionGeometrys);
|
|
if (geometryRefs2d == DimensionGeometry::isInvalid) {
|
|
QMessageBox::warning(Gui::getMainWindow(),
|
|
QObject::tr("Incorrect selection"),
|
|
QObject::tr("Cannot make dimension from selection"));
|
|
return;
|
|
}
|
|
//what 3d geometry configuration did we receive?
|
|
DimensionGeometry geometryRefs3d(DimensionGeometry::isInvalid);
|
|
if (geometryRefs2d == DimensionGeometry::isViewReference && !references3d.empty()) {
|
|
geometryRefs3d = validateDimSelection3d(
|
|
dvp, references3d, acceptableGeometry, minimumCounts, acceptableDimensionGeometrys);
|
|
if (geometryRefs3d == DimensionGeometry::isInvalid) {
|
|
QMessageBox::warning(Gui::getMainWindow(),
|
|
QObject::tr("Incorrect selection"),
|
|
QObject::tr("Cannot make dimension from selection"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_toApply2d = references2d;
|
|
if (references3d.empty()) {
|
|
m_toApply3d.clear();
|
|
} else {
|
|
m_toApply3d = references3d;
|
|
}
|
|
updateUi();
|
|
}
|
|
|
|
void TaskDimRepair::updateUi()
|
|
{
|
|
// if the dimension is very broken, it may not have a valid 2d view reference. This can happen if the
|
|
// restore process breaks and the reference target object does not get properly loaded.
|
|
|
|
DrawViewPart* viewPart = m_dim->getViewPart();
|
|
if (!viewPart && !m_toApply2d.empty()) {
|
|
viewPart = Base::freecad_cast<DrawViewPart*>(m_toApply2d.front().getObject());
|
|
}
|
|
|
|
std::string objName = viewPart ? viewPart->getNameInDocument() : "";
|
|
std::string objLabel = viewPart ? viewPart->Label.getValue() : "";
|
|
ui->leObject2d->setText(QString::fromStdString(objName + " / " + objLabel));
|
|
|
|
std::vector<std::string> subElements2d;
|
|
for (auto& ref : m_toApply2d) {
|
|
subElements2d.push_back(ref.getSubName());
|
|
}
|
|
std::vector<std::string> labelsInOut(subElements2d.size());
|
|
fillList(ui->lwGeometry2d, labelsInOut, subElements2d);
|
|
|
|
loadTableWidget(ui->twReferences3d, m_toApply3d);
|
|
}
|
|
|
|
void TaskDimRepair::loadTableWidget(QTableWidget* tw, ReferenceVector refs)
|
|
{
|
|
tw->clearContents();
|
|
tw->setRowCount(refs.size() + 1);
|
|
size_t iRow = 0;
|
|
for (auto& ref : refs) {
|
|
QString qName = QString::fromStdString(ref.getObject()->getNameInDocument());
|
|
QTableWidgetItem* itemName = new QTableWidgetItem(qName);
|
|
itemName->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
tw->setItem(iRow, 0, itemName);
|
|
QString qLabel = QString::fromStdString(std::string(ref.getObject()->Label.getValue()));
|
|
QTableWidgetItem* itemLabel = new QTableWidgetItem(qLabel);
|
|
itemLabel->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
tw->setItem(iRow, 1, itemLabel);
|
|
QString qSubName = QString::fromStdString(ref.getSubName());
|
|
QTableWidgetItem* itemSubName = new QTableWidgetItem(qSubName);
|
|
itemSubName->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
tw->setItem(iRow, 2, itemSubName);
|
|
iRow++;
|
|
}
|
|
}
|
|
|
|
void TaskDimRepair::fillList(QListWidget* lwItems, std::vector<std::string> labels,
|
|
std::vector<std::string> names)
|
|
{
|
|
QListWidgetItem* item;
|
|
QString qLabel;
|
|
QString qName;
|
|
QString qText;
|
|
int labelCount = labels.size();
|
|
int i = 0;
|
|
lwItems->clear();
|
|
for (; i < labelCount; i++) {
|
|
qLabel = QString::fromStdString(labels[i]);
|
|
qName = QString::fromStdString(names[i]);
|
|
qText = QStringLiteral("%1 %2").arg(qName, qLabel);
|
|
item = new QListWidgetItem(qText, lwItems);
|
|
item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
|
item->setData(Qt::UserRole, qName);
|
|
}
|
|
}
|
|
void TaskDimRepair::replaceReferences()
|
|
{
|
|
if (!m_dim || m_toApply2d.empty()) {
|
|
return;
|
|
}
|
|
|
|
m_dim->setReferences2d(m_toApply2d);
|
|
|
|
if (!m_toApply3d.empty()) {
|
|
m_dim->setReferences3d(m_toApply3d);
|
|
}
|
|
}
|
|
|
|
bool TaskDimRepair::accept()
|
|
{
|
|
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
|
|
|
|
Gui::Command::openCommand(tr("Repair dimension").toStdString().c_str());
|
|
replaceReferences();
|
|
Gui::Command::commitCommand();
|
|
|
|
m_dim->recomputeFeature();
|
|
Gui::Selection().clearSelection();
|
|
return true;
|
|
}
|
|
|
|
bool TaskDimRepair::reject()
|
|
{
|
|
restoreDimState();
|
|
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
|
|
Gui::Selection().clearSelection();
|
|
return false;
|
|
}
|
|
|
|
void TaskDimRepair::changeEvent(QEvent* e)
|
|
{
|
|
if (e->type() == QEvent::LanguageChange) {
|
|
ui->retranslateUi(this);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
TaskDlgDimReference::TaskDlgDimReference(TechDraw::DrawViewDimension* inDvd)
|
|
: TaskDialog()
|
|
{
|
|
widget = new TaskDimRepair(inDvd);
|
|
taskbox = new Gui::TaskView::TaskBox(
|
|
Gui::BitmapFactory().pixmap("TechDraw_DimensionRepair"), widget->windowTitle(), true, 0);
|
|
taskbox->groupLayout()->addWidget(widget);
|
|
Content.push_back(taskbox);
|
|
}
|
|
|
|
|
|
TaskDlgDimReference::~TaskDlgDimReference()
|
|
{}
|
|
|
|
void TaskDlgDimReference::update()
|
|
{
|
|
//widget->updateTask();
|
|
}
|
|
|
|
//==== calls from the TaskView ===============================================================
|
|
void TaskDlgDimReference::open()
|
|
{}
|
|
|
|
void TaskDlgDimReference::clicked(int i)
|
|
{
|
|
Q_UNUSED(i);
|
|
}
|
|
|
|
bool TaskDlgDimReference::accept()
|
|
{
|
|
widget->accept();
|
|
return true;
|
|
}
|
|
|
|
bool TaskDlgDimReference::reject()
|
|
{
|
|
widget->reject();
|
|
return true;
|
|
}
|
|
|
|
#include <Mod/TechDraw/Gui/moc_TaskDimRepair.cpp>
|