fixes 0003861: Sketch change plane when changing Attachment Offset (UI quirk)

This commit is contained in:
wmayer
2019-03-12 22:54:37 +01:00
parent 4e8a684a6d
commit 8bcd3aa338
2 changed files with 121 additions and 56 deletions

View File

@@ -26,6 +26,7 @@
#include <QDockWidget>
#include <QMessageBox>
#include <QClipboard>
#include <QMetaObject>
#include "Placement.h"
#include "ui_Placement.h"
@@ -82,6 +83,7 @@ public:
Placement::Placement(QWidget* parent, Qt::WindowFlags fl)
: Gui::LocationDialog(parent, fl)
, changeProperty(false)
{
selectionObjects = Gui::Selection().getSelectionEx();
@@ -138,9 +140,28 @@ void Placement::showDefaultButtons(bool ok)
ui->applyButton->setVisible(ok);
}
void Placement::open()
{
if (propertyName != "Placement") {
changeProperty = true;
openTransaction();
}
}
void Placement::slotActiveDocument(const Gui::Document& doc)
{
documents.insert(doc.getDocument()->getName());
if (changeProperty) {
QMetaObject::invokeMethod(this, "openTransaction", Qt::QueuedConnection);
}
}
void Placement::openTransaction()
{
App::Document* activeDoc = App::GetApplication().getActiveDocument();
if (activeDoc)
activeDoc->openTransaction("Placement");
}
QWidget* Placement::getInvalidInput() const
@@ -159,22 +180,28 @@ void Placement::revertTransformation()
Gui::Document* document = Application::Instance->getDocument(it->c_str());
if (!document) continue;
std::vector<App::DocumentObject*> obj = document->getDocument()->
getObjectsOfType(App::DocumentObject::getClassTypeId());
if (!obj.empty()) {
for (std::vector<App::DocumentObject*>::iterator it=obj.begin();it!=obj.end();++it) {
std::map<std::string,App::Property*> props;
(*it)->getPropertyMap(props);
// search for the placement property
std::map<std::string,App::Property*>::iterator jt;
jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
if (jt != props.end()) {
Base::Placement cur = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
Gui::ViewProvider* vp = document->getViewProvider(*it);
if (vp) vp->setTransformation(cur.toMatrix());
if (!changeProperty) {
std::vector<App::DocumentObject*> obj = document->getDocument()->
getObjectsOfType(App::DocumentObject::getClassTypeId());
if (!obj.empty()) {
for (std::vector<App::DocumentObject*>::iterator it=obj.begin();it!=obj.end();++it) {
std::map<std::string,App::Property*> props;
(*it)->getPropertyMap(props);
// search for the placement property
std::map<std::string,App::Property*>::iterator jt;
jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
if (jt != props.end()) {
App::PropertyPlacement* property = static_cast<App::PropertyPlacement*>(jt->second);
Base::Placement cur = property->getValue();
Gui::ViewProvider* vp = document->getViewProvider(*it);
if (vp) vp->setTransformation(cur.toMatrix());
}
}
}
}
else {
document->abortCommand();
}
}
}
@@ -194,14 +221,20 @@ void Placement::applyPlacement(const Base::Placement& p, bool incremental)
std::map<std::string,App::Property*>::iterator jt;
jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
if (jt != props.end()) {
Base::Placement cur = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
App::PropertyPlacement* property = static_cast<App::PropertyPlacement*>(jt->second);
Base::Placement cur = property->getValue();
if (incremental)
cur = p * cur;
else
cur = p;
Gui::ViewProvider* vp = document->getViewProvider(*it);
if (vp) vp->setTransformation(cur.toMatrix());
if (!changeProperty) {
Gui::ViewProvider* vp = document->getViewProvider(*it);
if (vp) vp->setTransformation(cur.toMatrix());
}
else {
property->setValue(cur);
}
}
}
}
@@ -215,47 +248,60 @@ void Placement::applyPlacement(const QString& data, bool incremental)
Gui::Document* document = Application::Instance->activeDocument();
if (!document) return;
std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType
(App::DocumentObject::getClassTypeId(), document->getDocument()->getName());
if (!sel.empty()) {
document->openCommand("Placement");
for (std::vector<App::DocumentObject*>::iterator it=sel.begin();it!=sel.end();++it) {
std::map<std::string,App::Property*> props;
(*it)->getPropertyMap(props);
// search for the placement property
std::map<std::string,App::Property*>::iterator jt;
jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
if (jt != props.end()) {
QString cmd;
if (incremental)
cmd = QString::fromLatin1(
"App.getDocument(\"%1\").%2.%3=%4.multiply(App.getDocument(\"%1\").%2.%3)")
.arg(QLatin1String((*it)->getDocument()->getName()))
.arg(QLatin1String((*it)->getNameInDocument()))
.arg(QLatin1String(this->propertyName.c_str()))
.arg(data);
else {
cmd = QString::fromLatin1(
"App.getDocument(\"%1\").%2.%3=%4")
.arg(QLatin1String((*it)->getDocument()->getName()))
.arg(QLatin1String((*it)->getNameInDocument()))
.arg(QLatin1String(this->propertyName.c_str()))
.arg(data);
}
Gui::Command::runCommand(Gui::Command::App, cmd.toLatin1());
}
}
// When directly changing the property we now only have to commit the transaction,
// do a recompute and open a new transaction
if (changeProperty) {
document->commitCommand();
try {
document->getDocument()->recompute();
}
catch (...) {
}
document->openCommand("Placement");
}
else {
Base::Console().Warning("No object selected.\n");
std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType
(App::DocumentObject::getClassTypeId(), document->getDocument()->getName());
if (!sel.empty()) {
document->openCommand("Placement");
for (std::vector<App::DocumentObject*>::iterator it=sel.begin();it!=sel.end();++it) {
std::map<std::string,App::Property*> props;
(*it)->getPropertyMap(props);
// search for the placement property
std::map<std::string,App::Property*>::iterator jt;
jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
if (jt != props.end()) {
QString cmd;
if (incremental)
cmd = QString::fromLatin1(
"App.getDocument(\"%1\").%2.%3=%4.multiply(App.getDocument(\"%1\").%2.%3)")
.arg(QLatin1String((*it)->getDocument()->getName()))
.arg(QLatin1String((*it)->getNameInDocument()))
.arg(QLatin1String(this->propertyName.c_str()))
.arg(data);
else {
cmd = QString::fromLatin1(
"App.getDocument(\"%1\").%2.%3=%4")
.arg(QLatin1String((*it)->getDocument()->getName()))
.arg(QLatin1String((*it)->getNameInDocument()))
.arg(QLatin1String(this->propertyName.c_str()))
.arg(data);
}
Gui::Command::runCommand(Gui::Command::App, cmd.toLatin1());
}
}
document->commitCommand();
try {
document->getDocument()->recompute();
}
catch (...) {
}
}
else {
Base::Console().Warning("No object selected.\n");
}
}
}
@@ -353,7 +399,8 @@ void Placement::on_selectedVertex_clicked()
Base::Vector3d axis;
if (firstSelected==picked[0]){
axis = Base::Vector3d(picked[1]-picked[0]);
} else {
}
else {
axis = Base::Vector3d(picked[0]-picked[1]);
}
double length = axis.Length();
@@ -361,7 +408,8 @@ void Placement::on_selectedVertex_clicked()
if (QApplication::keyboardModifiers() == Qt::ShiftModifier){ //copy to clipboard on Shift+click
QLocale loc;
QApplication::clipboard()->setText(loc.toString(length,'g',8));
}else {
}
else {
Base::Console().Message("(Shift + click Selected points button to copy distance to clipboard)\n");
}
axis.Normalize();
@@ -371,7 +419,8 @@ void Placement::on_selectedVertex_clicked()
ui->rotationInput->setCurrentIndex(0); //use rotation with axis instead of euler
ui->stackedWidget->setCurrentIndex(0);
success=true;
} else if (picked.size() == 3){
}
else if (picked.size() == 3){
/* User selected 3 points, so we find the plane defined by those
* and use the normal vector that contains the first point picked
* as the axis of rotation.
@@ -381,10 +430,12 @@ void Placement::on_selectedVertex_clicked()
if (picked[0] == firstSelected){
a = picked[1];
c = picked[2];
} else if (picked[1]==firstSelected){
}
else if (picked[1]==firstSelected){
a = picked[0];
c = picked[2];
} else if (picked[2] == firstSelected){
}
else if (picked[2] == firstSelected){
a = picked[0];
c = picked[1];
}
@@ -416,7 +467,8 @@ void Placement::on_selectedVertex_clicked()
QLocale loc;
QApplication::clipboard()->setText(loc.toString(targetAngle,'g',8));
Base::Console().Message("(Angle copied to clipboard, but you might need to use a negative (-) angle sometimes.)\n");
} else {
}
else {
Base::Console().Message("(Shift + click Selected points button to copy angle to clipboard)\n");
}
rot.setValue(norm, angle);
@@ -459,7 +511,8 @@ void Placement::on_applyAxial_clicked()
Qt::KeyboardModifiers km = QApplication::keyboardModifiers();
if (km == Qt::ShiftModifier){ //go opposite direction on Shift+click
newPos = Base::Vector3d(curPos.x-(axis.x*axPos),curPos.y-(axis.y*axPos),curPos.z-(axis.z*axPos));
} else {
}
else {
newPos = Base::Vector3d(curPos.x+(axis.x*axPos),curPos.y+(axis.y*axPos),curPos.z+(axis.z*axPos));
}
ui->xPos->setValue(Base::Quantity(newPos.x,Base::Unit::Length));
@@ -772,6 +825,11 @@ TaskPlacement::~TaskPlacement()
// automatically deleted in the sub-class
}
void TaskPlacement::open()
{
widget->open();
}
void TaskPlacement::setPropertyName(const QString& name)
{
widget->propertyName = (const char*)name.toLatin1();

View File

@@ -57,10 +57,12 @@ public:
void showDefaultButtons(bool);
protected:
void open();
void changeEvent(QEvent *e);
void keyPressEvent(QKeyEvent*);
private Q_SLOTS:
void openTransaction();
void on_applyButton_clicked();
void on_applyIncrementalPlacement_toggled(bool);
void onPlacementChanged(int);
@@ -101,6 +103,10 @@ private:
* after user selects points and clicks Selected point(s)
*/
std::vector<SelectionObject> selectionObjects;
/** If false apply the placement directly to the transform nodes,
* otherwise change the placement property.
*/
bool changeProperty;
friend class TaskPlacement;
};
@@ -132,6 +138,7 @@ public:
bool reject();
void clicked(int id);
void open();
bool isAllowedAlterDocument(void) const
{ return true; }
bool isAllowedAlterView(void) const