00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #include <QSignalMapper>
00026 #include <QDockWidget>
00027
00028 #include "Placement.h"
00029 #include "ui_Placement.h"
00030 #include <Gui/DockWindowManager.h>
00031 #include <Gui/Application.h>
00032 #include <Gui/Document.h>
00033 #include <Gui/Selection.h>
00034 #include <Gui/ViewProvider.h>
00035 #include <App/Document.h>
00036 #include <App/PropertyGeo.h>
00037 #include <Base/Console.h>
00038
00039 using namespace Gui::Dialog;
00040
00041 namespace Gui { namespace Dialog {
00042 class find_placement
00043 {
00044 public:
00045 find_placement(const std::string& name) : propertyname(name)
00046 {
00047 }
00048 bool operator () (const std::pair<std::string, App::Property*>& elem) const
00049 {
00050 if (elem.first == propertyname) {
00051 return elem.second->isDerivedFrom
00052 (Base::Type::fromName("App::PropertyPlacement"));
00053 }
00054
00055 return false;
00056 }
00057
00058 std::string propertyname;
00059 };
00060
00061 }
00062 }
00063
00064
00065
00066 Placement::Placement(QWidget* parent, Qt::WFlags fl)
00067 : Gui::LocationDialog(parent, fl)
00068 {
00069 propertyName = "Placement";
00070 ui = new Ui_PlacementComp(this);
00071 ui->applyPlacementChange->hide();
00072
00073 ui->angle->setSuffix(QString::fromUtf8(" \xc2\xb0"));
00074 ui->yawAngle->setSuffix(QString::fromUtf8(" \xc2\xb0"));
00075 ui->pitchAngle->setSuffix(QString::fromUtf8(" \xc2\xb0"));
00076 ui->rollAngle->setSuffix(QString::fromUtf8(" \xc2\xb0"));
00077
00078
00079 signalMapper = new QSignalMapper(this);
00080 connect(this, SIGNAL(directionChanged()), signalMapper, SLOT(map()));
00081 signalMapper->setMapping(this, 0);
00082
00083 int id = 1;
00084 QList<QDoubleSpinBox*> sb = this->findChildren<QDoubleSpinBox*>();
00085 for (QList<QDoubleSpinBox*>::iterator it = sb.begin(); it != sb.end(); ++it) {
00086 connect(*it, SIGNAL(valueChanged(double)), signalMapper, SLOT(map()));
00087 signalMapper->setMapping(*it, id++);
00088 }
00089
00090 connect(signalMapper, SIGNAL(mapped(int)),
00091 this, SLOT(onPlacementChanged(int)));
00092 }
00093
00094 Placement::~Placement()
00095 {
00096 delete ui;
00097 }
00098
00099 void Placement::showDefaultButtons(bool ok)
00100 {
00101 ui->oKButton->setVisible(ok);
00102 ui->closeButton->setVisible(ok);
00103 ui->applyButton->setVisible(ok);
00104 }
00105
00106 void Placement::applyPlacement(const Base::Placement& p, bool incremental, bool data)
00107 {
00108 Gui::Document* document = Application::Instance->activeDocument();
00109 if (!document) return;
00110
00111 std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType
00112 (App::DocumentObject::getClassTypeId(), document->getDocument()->getName());
00113 if (!sel.empty()) {
00114 if (data) {
00115 document->openCommand("Placement");
00116 for (std::vector<App::DocumentObject*>::iterator it=sel.begin();it!=sel.end();++it) {
00117 std::map<std::string,App::Property*> props;
00118 (*it)->getPropertyMap(props);
00119
00120 std::map<std::string,App::Property*>::iterator jt;
00121 jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
00122 if (jt != props.end()) {
00123 Base::Placement cur = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
00124 if (incremental)
00125 cur = p * cur;
00126 else
00127 cur = p;
00128
00129 Base::Vector3d pos = cur.getPosition();
00130 const Base::Rotation& rt = cur.getRotation();
00131 QString cmd = QString::fromAscii(
00132 "App.getDocument(\"%1\").%2.Placement="
00133 "App.Placement("
00134 "App.Vector(%3,%4,%5),"
00135 "App.Rotation(%6,%7,%8,%9))\n")
00136 .arg(QLatin1String((*it)->getDocument()->getName()))
00137 .arg(QLatin1String((*it)->getNameInDocument()))
00138 .arg(pos.x,0,'g',6)
00139 .arg(pos.y,0,'g',6)
00140 .arg(pos.z,0,'g',6)
00141 .arg(rt[0],0,'g',6)
00142 .arg(rt[1],0,'g',6)
00143 .arg(rt[2],0,'g',6)
00144 .arg(rt[3],0,'g',6);
00145 Application::Instance->runPythonCode((const char*)cmd.toAscii());
00146 }
00147 }
00148
00149 document->commitCommand();
00150 }
00151
00152 else {
00153 for (std::vector<App::DocumentObject*>::iterator it=sel.begin();it!=sel.end();++it) {
00154 std::map<std::string,App::Property*> props;
00155 (*it)->getPropertyMap(props);
00156
00157 std::map<std::string,App::Property*>::iterator jt;
00158 jt = std::find_if(props.begin(), props.end(), find_placement(this->propertyName));
00159 if (jt != props.end()) {
00160 Base::Placement cur = static_cast<App::PropertyPlacement*>(jt->second)->getValue();
00161 if (incremental)
00162 cur = p * cur;
00163 else
00164 cur = p;
00165
00166 Gui::ViewProvider* vp = document->getViewProvider(*it);
00167 if (vp) vp->setTransformation(cur.toMatrix());
00168 }
00169 }
00170 }
00171 }
00172 else {
00173 Base::Console().Warning("No object selected.\n");
00174 }
00175 }
00176
00177 void Placement::onPlacementChanged(int)
00178 {
00179
00180
00181
00182
00183 bool incr = ui->applyIncrementalPlacement->isChecked();
00184 Base::Placement plm = this->getPlacement();
00185 applyPlacement(plm, incr, false);
00186
00187 QVariant data = QVariant::fromValue<Base::Placement>(plm);
00188 placementChanged(data, incr, false);
00189 }
00190
00191 void Placement::on_applyIncrementalPlacement_toggled(bool on)
00192 {
00193 if (on) {
00194 this->ref = getPlacementData();
00195 on_resetButton_clicked();
00196 }
00197 else {
00198 Base::Placement p = getPlacementData();
00199 p = p * this->ref;
00200 setPlacementData(p);
00201 onPlacementChanged(0);
00202 }
00203 }
00204
00205 void Placement::reject()
00206 {
00207 Base::Placement plm;
00208 applyPlacement(plm, true, false);
00209
00210 QVariant data = QVariant::fromValue<Base::Placement>(plm);
00211 placementChanged(data, true, false);
00212
00213 QDialog::reject();
00214 }
00215
00216 void Placement::accept()
00217 {
00218 on_applyButton_clicked();
00219 QDialog::accept();
00220 }
00221
00222 void Placement::on_applyButton_clicked()
00223 {
00224
00225
00226
00227
00228 bool incr = ui->applyIncrementalPlacement->isChecked();
00229 Base::Placement plm = this->getPlacement();
00230 applyPlacement(plm, incr, true);
00231
00232 QVariant data = QVariant::fromValue<Base::Placement>(plm);
00233 placementChanged(data, incr, true);
00234
00235 if (ui->applyIncrementalPlacement->isChecked()) {
00236 QList<QDoubleSpinBox*> sb = this->findChildren<QDoubleSpinBox*>();
00237 for (QList<QDoubleSpinBox*>::iterator it = sb.begin(); it != sb.end(); ++it) {
00238 (*it)->blockSignals(true);
00239 (*it)->setValue(0.0);
00240 (*it)->blockSignals(false);
00241 }
00242 }
00243 }
00244
00245 void Placement::on_resetButton_clicked()
00246 {
00247 QList<QDoubleSpinBox*> sb = this->findChildren<QDoubleSpinBox*>();
00248 for (QList<QDoubleSpinBox*>::iterator it = sb.begin(); it != sb.end(); ++it) {
00249 (*it)->blockSignals(true);
00250 (*it)->setValue(0.0);
00251 (*it)->blockSignals(false);
00252 }
00253
00254 onPlacementChanged(0);
00255 }
00256
00257 void Placement::directionActivated(int index)
00258 {
00259 if (ui->directionActivated(this, index)) {
00260 directionChanged();
00261 }
00262 }
00263
00264 Base::Vector3f Placement::getDirection() const
00265 {
00266 return ui->getDirection();
00267 }
00268
00269 void Placement::setPlacement(const Base::Placement& p)
00270 {
00271 setPlacementData(p);
00272 }
00273
00274 void Placement::setPlacementData(const Base::Placement& p)
00275 {
00276 signalMapper->blockSignals(true);
00277 ui->xPos->setValue(p.getPosition().x);
00278 ui->yPos->setValue(p.getPosition().y);
00279 ui->zPos->setValue(p.getPosition().z);
00280
00281 double Y,P,R;
00282 p.getRotation().getYawPitchRoll(Y,P,R);
00283 ui->yawAngle->setValue(Y);
00284 ui->pitchAngle->setValue(P);
00285 ui->rollAngle->setValue(R);
00286
00287
00288 bool newitem = true;
00289 double angle;
00290 Base::Vector3d axis;
00291 p.getRotation().getValue(axis, angle);
00292 ui->angle->setValue(angle*180.0/D_PI);
00293 Base::Vector3f dir((float)axis.x,(float)axis.y,(float)axis.z);
00294 for (int i=0; i<ui->direction->count()-1; i++) {
00295 QVariant data = ui->direction->itemData (i);
00296 if (data.canConvert<Base::Vector3f>()) {
00297 const Base::Vector3f val = data.value<Base::Vector3f>();
00298 if (val == dir) {
00299 ui->direction->setCurrentIndex(i);
00300 newitem = false;
00301 break;
00302 }
00303 }
00304 }
00305
00306 if (newitem) {
00307
00308 QString display = QString::fromAscii("(%1,%2,%3)")
00309 .arg(dir.x)
00310 .arg(dir.y)
00311 .arg(dir.z);
00312 ui->direction->insertItem(ui->direction->count()-1, display,
00313 QVariant::fromValue<Base::Vector3f>(dir));
00314 ui->direction->setCurrentIndex(ui->direction->count()-2);
00315 }
00316 signalMapper->blockSignals(false);
00317 }
00318
00319 Base::Placement Placement::getPlacement() const
00320 {
00321 Base::Placement p = getPlacementData();
00322 return p;
00323 }
00324
00325 Base::Placement Placement::getPlacementData() const
00326 {
00327 int index = ui->rotationInput->currentIndex();
00328 Base::Rotation rot;
00329 Base::Vector3d pos;
00330 Base::Vector3d cnt;
00331
00332 pos = Base::Vector3d(ui->xPos->value(),ui->yPos->value(),ui->zPos->value());
00333 cnt = Base::Vector3d(ui->xCnt->value(),ui->yCnt->value(),ui->zCnt->value());
00334
00335 if (index == 0) {
00336 Base::Vector3f dir = getDirection();
00337 rot.setValue(Base::Vector3d(dir.x,dir.y,dir.z),ui->angle->value()*D_PI/180.0);
00338 }
00339 else if (index == 1) {
00340 rot.setYawPitchRoll(
00341 ui->yawAngle->value(),
00342 ui->pitchAngle->value(),
00343 ui->rollAngle->value());
00344 }
00345
00346 Base::Placement p(pos, rot, cnt);
00347 return p;
00348 }
00349
00350 void Placement::changeEvent(QEvent *e)
00351 {
00352 if (e->type() == QEvent::LanguageChange) {
00353 ui->retranslate(this);
00354 }
00355 else {
00356 QDialog::changeEvent(e);
00357 }
00358 }
00359
00360
00361
00362
00363
00364 DockablePlacement::DockablePlacement(QWidget* parent, Qt::WFlags fl) : Placement(parent, fl)
00365 {
00366 Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
00367 QDockWidget* dw = pDockMgr->addDockWindow(QT_TR_NOOP("Placement"),
00368 this, Qt::BottomDockWidgetArea);
00369 dw->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable);
00370 dw->show();
00371 }
00372
00373 DockablePlacement::~DockablePlacement()
00374 {
00375 }
00376
00377 void DockablePlacement::accept()
00378 {
00379
00380 Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
00381 pDockMgr->removeDockWindow(this);
00382 Placement::accept();
00383 }
00384
00385 void DockablePlacement::reject()
00386 {
00387
00388 Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
00389 pDockMgr->removeDockWindow(this);
00390 Placement::reject();
00391 }
00392
00393
00394
00395
00396
00397 TaskPlacement::TaskPlacement()
00398 {
00399 this->setButtonPosition(TaskPlacement::South);
00400 widget = new Placement();
00401 widget->showDefaultButtons(false);
00402 taskbox = new Gui::TaskView::TaskBox(QPixmap(), widget->windowTitle(),true, 0);
00403 taskbox->groupLayout()->addWidget(widget);
00404
00405 Content.push_back(taskbox);
00406 connect(widget, SIGNAL(placementChanged(const QVariant &, bool, bool)),
00407 this, SLOT(slotPlacementChanged(const QVariant &, bool, bool)));
00408 }
00409
00410 TaskPlacement::~TaskPlacement()
00411 {
00412
00413 }
00414
00415 void TaskPlacement::setPropertyName(const QString& name)
00416 {
00417 widget->propertyName = (const char*)name.toLatin1();
00418 }
00419
00420 QDialogButtonBox::StandardButtons TaskPlacement::getStandardButtons() const
00421 {
00422 return QDialogButtonBox::Ok|
00423 QDialogButtonBox::Cancel|
00424 QDialogButtonBox::Apply;
00425 }
00426
00427 void TaskPlacement::setPlacement(const Base::Placement& p)
00428 {
00429 widget->setPlacement(p);
00430 }
00431
00432 void TaskPlacement::slotPlacementChanged(const QVariant & p, bool incr, bool data)
00433 {
00434 placementChanged(p, incr, data);
00435 }
00436
00437 bool TaskPlacement::accept()
00438 {
00439 widget->accept();
00440 return (widget->result() == QDialog::Accepted);
00441 }
00442
00443 bool TaskPlacement::reject()
00444 {
00445 widget->reject();
00446 return (widget->result() == QDialog::Rejected);
00447 }
00448
00449 void TaskPlacement::clicked(int id)
00450 {
00451 if (id == QDialogButtonBox::Apply) {
00452 widget->on_applyButton_clicked();
00453 }
00454 }
00455
00456 #include "moc_Placement.cpp"