PropertyItem.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2004 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <algorithm>
00028 # include <QComboBox>
00029 # include <QFontDatabase>
00030 # include <QLayout>
00031 # include <QLocale>
00032 # include <QPixmap>
00033 # include <QSpinBox>
00034 # include <QTextStream>
00035 #endif
00036 
00037 #include <Base/Tools.h>
00038 #include <Base/UnitsApi.h>
00039 #include <App/Application.h>
00040 #include <App/Document.h>
00041 #include <App/DocumentObject.h>
00042 #include <App/PropertyGeo.h>
00043 #include <App/PropertyFile.h>
00044 #include <App/PropertyUnits.h>
00045 #include <Gui/Application.h>
00046 #include <Gui/Control.h>
00047 #include <Gui/Document.h>
00048 #include <Gui/ViewProviderDocumentObject.h>
00049 #include <Gui/Placement.h>
00050 #include <Gui/FileDialog.h>
00051 
00052 #include "PropertyItem.h"
00053 
00054 using namespace Gui::PropertyEditor;
00055 
00056 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyItem, Base::BaseClass);
00057 
00058 PropertyItem::PropertyItem() : parentItem(0), readonly(false)
00059 {
00060 }
00061 
00062 PropertyItem::~PropertyItem()
00063 {
00064     qDeleteAll(childItems);
00065 }
00066 
00067 void PropertyItem::reset()
00068 {
00069     qDeleteAll(childItems);
00070     childItems.clear();
00071 }
00072 
00073 void PropertyItem::setPropertyData(const std::vector<App::Property*>& items)
00074 {
00075     propertyItems = items;
00076     bool ro = true;
00077     for (std::vector<App::Property*>::const_iterator it = items.begin();
00078         it != items.end(); ++it) {
00079         App::PropertyContainer* parent = (*it)->getContainer();
00080         if (parent)
00081             ro &= parent->isReadOnly(*it);
00082     }
00083     this->setReadOnly(ro);
00084 }
00085 
00086 const std::vector<App::Property*>& PropertyItem::getPropertyData() const
00087 {
00088     return propertyItems;
00089 }
00090 
00091 void PropertyItem::setParent(PropertyItem* parent)
00092 {
00093     parentItem = parent;
00094 }
00095 
00096 PropertyItem *PropertyItem::parent() const
00097 {
00098     return parentItem;
00099 }
00100 
00101 void PropertyItem::appendChild(PropertyItem *item)
00102 {
00103     childItems.append(item);
00104 }
00105 
00106 PropertyItem *PropertyItem::child(int row)
00107 {
00108     return childItems.value(row);
00109 }
00110 
00111 int PropertyItem::childCount() const
00112 {
00113     return childItems.count();
00114 }
00115 
00116 int PropertyItem::columnCount() const
00117 {
00118     return 2;
00119 }
00120 
00121 void PropertyItem::setReadOnly(bool ro)
00122 {
00123     readonly = ro;
00124 }
00125 
00126 bool PropertyItem::isReadOnly() const
00127 {
00128     return readonly;
00129 }
00130 
00131 QVariant PropertyItem::toolTip(const App::Property* prop) const
00132 {
00133     return QVariant(QString::fromUtf8(prop->getDocumentation()));
00134 }
00135 
00136 QVariant PropertyItem::decoration(const App::Property* /*prop*/) const
00137 {
00138     return QVariant();
00139 }
00140 
00141 QVariant PropertyItem::toString(const QVariant& prop) const
00142 {
00143     return prop;
00144 }
00145 
00146 QVariant PropertyItem::value(const App::Property* /*prop*/) const
00147 {
00148     return QVariant();
00149 }
00150 
00151 void PropertyItem::setValue(const QVariant& /*value*/)
00152 {
00153 }
00154 
00155 QString PropertyItem::pythonIdentifier(const App::Property* prop) const
00156 {
00157     App::PropertyContainer* parent = prop->getContainer();
00158     if (parent->getTypeId() == App::Document::getClassTypeId()) {
00159         App::Document* doc = static_cast<App::Document*>(parent);
00160         QString docName = QString::fromAscii(App::GetApplication().getDocumentName(doc));
00161         QString propName = QString::fromAscii(parent->getName(prop));
00162         return QString::fromAscii("FreeCAD.getDocument(\"%1\").%2").arg(docName).arg(propName);
00163     }
00164     if (parent->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId())) {
00165         App::DocumentObject* obj = static_cast<App::DocumentObject*>(parent);
00166         App::Document* doc = obj->getDocument();
00167         QString docName = QString::fromAscii(App::GetApplication().getDocumentName(doc));
00168         QString objName = QString::fromAscii(obj->getNameInDocument());
00169         QString propName = QString::fromAscii(parent->getName(prop));
00170         return QString::fromAscii("FreeCAD.getDocument(\"%1\").getObject(\"%2\").%3")
00171             .arg(docName).arg(objName).arg(propName);
00172     }
00173     if (parent->getTypeId().isDerivedFrom(Gui::ViewProviderDocumentObject::getClassTypeId())) {
00174         App::DocumentObject* obj = static_cast<Gui::ViewProviderDocumentObject*>(parent)->getObject();
00175         App::Document* doc = obj->getDocument();
00176         QString docName = QString::fromAscii(App::GetApplication().getDocumentName(doc));
00177         QString objName = QString::fromAscii(obj->getNameInDocument());
00178         QString propName = QString::fromAscii(parent->getName(prop));
00179         return QString::fromAscii("FreeCADGui.getDocument(\"%1\").getObject(\"%2\").%3")
00180             .arg(docName).arg(objName).arg(propName);
00181     }
00182     return QString();
00183 }
00184 
00185 QWidget* PropertyItem::createEditor(QWidget* /*parent*/, const QObject* /*receiver*/, const char* /*method*/) const
00186 {
00187     return 0;
00188 }
00189 
00190 void PropertyItem::setEditorData(QWidget * /*editor*/, const QVariant& /*data*/) const
00191 {
00192 }
00193 
00194 QVariant PropertyItem::editorData(QWidget * /*editor*/) const
00195 {
00196     return QVariant();
00197 }
00198 
00199 QString PropertyItem::propertyName() const
00200 {
00201     if (propName.isEmpty())
00202         return QLatin1String("<empty>");
00203     return propName;
00204 }
00205 
00206 void PropertyItem::setPropertyName(const QString& name)
00207 {
00208     setObjectName(name);
00209     QString display;
00210     bool upper = false;
00211     for (int i=0; i<name.length(); i++) {
00212         if (name[i].isUpper() && !display.isEmpty()) {
00213             // if there is a sequence of capital letters do not insert spaces
00214             if (!upper)
00215                 display += QLatin1String(" ");
00216         }
00217         upper = name[i].isUpper();
00218         display += name[i];
00219     }
00220 
00221     propName = display;
00222 }
00223 
00224 void PropertyItem::setPropertyValue(const QString& value)
00225 {
00226     for (std::vector<App::Property*>::const_iterator it = propertyItems.begin();
00227         it != propertyItems.end(); ++it) {
00228         App::PropertyContainer* parent = (*it)->getContainer();
00229         if (parent && !parent->isReadOnly(*it)) {
00230             QString cmd = QString::fromAscii("%1 = %2").arg(pythonIdentifier(*it)).arg(value);
00231             Gui::Application::Instance->runPythonCode((const char*)cmd.toUtf8());
00232         }
00233     }
00234 }
00235 
00236 QVariant PropertyItem::data(int column, int role) const
00237 {
00238     // property name
00239     if (column == 0) {
00240         if (role == Qt::DisplayRole)
00241             return propertyName();
00242         // no properties set
00243         if (propertyItems.empty())
00244             return QVariant();
00245         else if (role == Qt::ToolTipRole)
00246             return toolTip(propertyItems[0]);
00247         else
00248             return QVariant();
00249     }
00250     else {
00251         // no properties set
00252         if (propertyItems.empty()) {
00253             PropertyItem* parent = this->parent();
00254             if (!parent || !parent->parent())
00255                 return QVariant();
00256             if (role == Qt::EditRole)
00257                 return parent->property(qPrintable(objectName()));
00258             else if (role == Qt::DisplayRole) {
00259                 QVariant val = parent->property(qPrintable(objectName()));
00260                 return toString(val);
00261 
00262             }
00263             else
00264                 return QVariant();
00265         }
00266         if (role == Qt::EditRole)
00267             return value(propertyItems[0]);
00268         else if (role == Qt::DecorationRole)
00269             return decoration(propertyItems[0]);
00270         else if (role == Qt::DisplayRole)
00271             return toString(value(propertyItems[0]));
00272         else if (role == Qt::ToolTipRole)
00273             return toolTip(propertyItems[0]);
00274         else
00275             return QVariant();
00276     }
00277 }
00278 
00279 bool PropertyItem::setData (const QVariant& value)
00280 {
00281     // This is the basic mechanism to set the value to
00282     // a property and if no property is set for this item
00283     // it delegates it to its parent which sets then the
00284     // property or delegates again to its parent...
00285     if (propertyItems.empty()) {
00286         PropertyItem* parent = this->parent();
00287         if (!parent || !parent->parent())
00288             return false;
00289         parent->setProperty(qPrintable(objectName()),value);
00290         return true;
00291     }
00292     else {
00293         setValue(value);
00294         return true;
00295     }
00296 }
00297 
00298 Qt::ItemFlags PropertyItem::flags(int column) const
00299 {
00300     Qt::ItemFlags basicFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00301     if (column == 1 && !isReadOnly())
00302         return basicFlags | Qt::ItemIsEditable;
00303     else
00304         return basicFlags;
00305 }
00306 
00307 int PropertyItem::row() const
00308 {
00309     if (parentItem)
00310         return parentItem->childItems.indexOf(const_cast<PropertyItem*>(this));
00311 
00312     return 0;
00313 }
00314 
00315 // --------------------------------------------------------------------
00316 
00317 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyStringItem, Gui::PropertyEditor::PropertyItem);
00318 
00319 PropertyStringItem::PropertyStringItem()
00320 {
00321 }
00322 
00323 QVariant PropertyStringItem::value(const App::Property* prop) const
00324 {
00325     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyString::getClassTypeId()));
00326 
00327     std::string value = static_cast<const App::PropertyString*>(prop)->getValue();
00328     return QVariant(QString::fromUtf8(value.c_str()));
00329 }
00330 
00331 void PropertyStringItem::setValue(const QVariant& value)
00332 {
00333     if (!value.canConvert(QVariant::String))
00334         return;
00335     QString val = value.toString();
00336     QString data = QString::fromAscii("\"%1\"").arg(val);
00337     setPropertyValue(data);
00338 }
00339 
00340 QWidget* PropertyStringItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00341 {
00342     QLineEdit *le = new QLineEdit(parent);
00343     le->setFrame(false);
00344     QObject::connect(le, SIGNAL(textChanged(const QString&)), receiver, method);
00345     return le;
00346 }
00347 
00348 void PropertyStringItem::setEditorData(QWidget *editor, const QVariant& data) const
00349 {
00350     QLineEdit *le = qobject_cast<QLineEdit*>(editor);
00351     le->setText(data.toString());
00352 }
00353 
00354 QVariant PropertyStringItem::editorData(QWidget *editor) const
00355 {
00356     QLineEdit *le = qobject_cast<QLineEdit*>(editor);
00357     return QVariant(le->text());
00358 }
00359 
00360 // --------------------------------------------------------------------
00361 
00362 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyFontItem, Gui::PropertyEditor::PropertyItem);
00363 
00364 PropertyFontItem::PropertyFontItem()
00365 {
00366 }
00367 
00368 QVariant PropertyFontItem::value(const App::Property* prop) const
00369 {
00370     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyFont::getClassTypeId()));
00371 
00372     std::string value = static_cast<const App::PropertyFont*>(prop)->getValue();
00373     return QVariant(QString::fromUtf8(value.c_str()));
00374 }
00375 
00376 void PropertyFontItem::setValue(const QVariant& value)
00377 {
00378     if (!value.canConvert(QVariant::String))
00379         return;
00380     QString val = value.toString();
00381     QString data = QString::fromAscii("\"%1\"").arg(val);
00382     setPropertyValue(data);
00383 }
00384 
00385 QWidget* PropertyFontItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00386 {
00387     QComboBox *cb = new QComboBox(parent);
00388     cb->setFrame(false);
00389     QObject::connect(cb, SIGNAL(activated(const QString&)), receiver, method);
00390     return cb;
00391 }
00392 
00393 void PropertyFontItem::setEditorData(QWidget *editor, const QVariant& data) const
00394 {
00395     QComboBox *cb = qobject_cast<QComboBox*>(editor);
00396     QFontDatabase fdb;
00397     QStringList familyNames = fdb.families(QFontDatabase::Any);
00398     cb->addItems(familyNames);
00399     int index = familyNames.indexOf(data.toString());
00400     cb->setCurrentIndex(index);
00401 }
00402 
00403 QVariant PropertyFontItem::editorData(QWidget *editor) const
00404 {
00405     QComboBox *cb = qobject_cast<QComboBox*>(editor);
00406     return QVariant(cb->currentText());
00407 }
00408 
00409 // --------------------------------------------------------------------
00410 
00411 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertySeparatorItem, Gui::PropertyEditor::PropertyItem);
00412 
00413 QWidget* PropertySeparatorItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00414 {
00415     return 0;
00416 }
00417 
00418 // --------------------------------------------------------------------
00419 
00420 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyIntegerItem, Gui::PropertyEditor::PropertyItem);
00421 
00422 PropertyIntegerItem::PropertyIntegerItem()
00423 {
00424 }
00425 
00426 QVariant PropertyIntegerItem::value(const App::Property* prop) const
00427 {
00428     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyInteger::getClassTypeId()));
00429 
00430     int value = (int)static_cast<const App::PropertyInteger*>(prop)->getValue();
00431     return QVariant(value);
00432 }
00433 
00434 void PropertyIntegerItem::setValue(const QVariant& value)
00435 {
00436     if (!value.canConvert(QVariant::Int))
00437         return;
00438     int val = value.toInt();
00439     QString data = QString::fromAscii("%1").arg(val);
00440     setPropertyValue(data);
00441 }
00442 
00443 QWidget* PropertyIntegerItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00444 {
00445     QSpinBox *sb = new QSpinBox(parent);
00446     sb->setFrame(false);
00447     QObject::connect(sb, SIGNAL(valueChanged(int)), receiver, method);
00448     return sb;
00449 }
00450 
00451 void PropertyIntegerItem::setEditorData(QWidget *editor, const QVariant& data) const
00452 {
00453     QSpinBox *sb = qobject_cast<QSpinBox*>(editor);
00454     sb->setRange(INT_MIN, INT_MAX);
00455     sb->setValue(data.toInt());
00456 }
00457 
00458 QVariant PropertyIntegerItem::editorData(QWidget *editor) const
00459 {
00460     QSpinBox *sb = qobject_cast<QSpinBox*>(editor);
00461     return QVariant(sb->value());
00462 }
00463 
00464 // --------------------------------------------------------------------
00465 
00466 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyIntegerConstraintItem, Gui::PropertyEditor::PropertyItem);
00467 
00468 PropertyIntegerConstraintItem::PropertyIntegerConstraintItem()
00469 {
00470 }
00471 
00472 QVariant PropertyIntegerConstraintItem::value(const App::Property* prop) const
00473 {
00474     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyIntegerConstraint::getClassTypeId()));
00475 
00476     int value = (int)static_cast<const App::PropertyIntegerConstraint*>(prop)->getValue();
00477     return QVariant(value);
00478 }
00479 
00480 void PropertyIntegerConstraintItem::setValue(const QVariant& value)
00481 {
00482     if (!value.canConvert(QVariant::Int))
00483         return;
00484     int val = value.toInt();
00485     QString data = QString::fromAscii("%1").arg(val);
00486     setPropertyValue(data);
00487 }
00488 
00489 QWidget* PropertyIntegerConstraintItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00490 {
00491     QSpinBox *sb = new QSpinBox(parent);
00492     sb->setFrame(false);
00493     QObject::connect(sb, SIGNAL(valueChanged(int)), receiver, method);
00494     return sb;
00495 }
00496 
00497 void PropertyIntegerConstraintItem::setEditorData(QWidget *editor, const QVariant& /*data*/) const
00498 {
00499     const std::vector<App::Property*>& items = getPropertyData();
00500     App::PropertyIntegerConstraint* prop = (App::PropertyIntegerConstraint*)items[0];
00501 
00502     const App::PropertyIntegerConstraint::Constraints* c = 
00503         ((App::PropertyIntegerConstraint*)prop)->getConstraints();
00504     QSpinBox *sb = qobject_cast<QSpinBox*>(editor);
00505     if (c) {
00506         sb->setMinimum(c->LowerBound);
00507         sb->setMaximum(c->UpperBound);
00508         sb->setSingleStep(c->StepSize);
00509     }
00510     else {
00511         sb->setMinimum(INT_MIN);
00512         sb->setMaximum(INT_MAX);
00513     }
00514     sb->setValue(prop->getValue());
00515 }
00516 
00517 QVariant PropertyIntegerConstraintItem::editorData(QWidget *editor) const
00518 {
00519     QSpinBox *sb = qobject_cast<QSpinBox*>(editor);
00520     return QVariant(sb->value());
00521 }
00522 
00523 // --------------------------------------------------------------------
00524 
00525 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyFloatItem, Gui::PropertyEditor::PropertyItem);
00526 
00527 PropertyFloatItem::PropertyFloatItem()
00528 {
00529 }
00530 
00531 QVariant PropertyFloatItem::toString(const QVariant& prop) const
00532 {
00533     double value = prop.toDouble();
00534     QString data = QLocale::system().toString(value, 'f', 2);
00535     const std::vector<App::Property*>& props = getPropertyData();
00536     if (!props.empty()) {
00537         if (props.front()->getTypeId().isDerivedFrom(App::PropertyDistance::getClassTypeId())) {
00538             QString unit = Base::UnitsApi::getPrefUnitOf(Base::Length);
00539             unit.prepend(QLatin1String(" "));
00540             data += unit;
00541         }
00542         else if (props.front()->getTypeId().isDerivedFrom(App::PropertyLength::getClassTypeId())) {
00543             QString unit = Base::UnitsApi::getPrefUnitOf(Base::Length);
00544             unit.prepend(QLatin1String(" "));
00545             data += unit;
00546         }
00547         else if (props.front()->getTypeId().isDerivedFrom(App::PropertySpeed::getClassTypeId())) {
00548             //QString unit = Base::UnitsApi::getPrefUnitOf(Base::Acceleration);
00549             //unit.prepend(QLatin1String(" "));
00550             //data += unit;
00551         }
00552         else if (props.front()->getTypeId().isDerivedFrom(App::PropertyAcceleration::getClassTypeId())) {
00553             QString unit = Base::UnitsApi::getPrefUnitOf(Base::Acceleration);
00554             unit.prepend(QLatin1String(" "));
00555             data += unit;
00556         }
00557     }
00558 
00559     return QVariant(data);
00560 }
00561 
00562 QVariant PropertyFloatItem::value(const App::Property* prop) const
00563 {
00564     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyFloat::getClassTypeId()));
00565 
00566     double value = static_cast<const App::PropertyFloat*>(prop)->getValue();
00567     return QVariant(value);
00568 }
00569 
00570 void PropertyFloatItem::setValue(const QVariant& value)
00571 {
00572     if (!value.canConvert(QVariant::Double))
00573         return;
00574     double val = value.toDouble();
00575     QString data = QString::fromAscii("%1").arg(val,0,'f',2);
00576     setPropertyValue(data);
00577 }
00578 
00579 QWidget* PropertyFloatItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00580 {
00581     QDoubleSpinBox *sb = new QDoubleSpinBox(parent);
00582     sb->setFrame(false);
00583     QObject::connect(sb, SIGNAL(valueChanged(double)), receiver, method);
00584     return sb;
00585 }
00586 
00587 void PropertyFloatItem::setEditorData(QWidget *editor, const QVariant& data) const
00588 {
00589     QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(editor);
00590     sb->setRange((double)INT_MIN, (double)INT_MAX);
00591     sb->setValue(data.toDouble());
00592     const std::vector<App::Property*>& prop = getPropertyData();
00593     if (prop.empty())
00594         return;
00595     else if (prop.front()->getTypeId().isDerivedFrom(App::PropertyDistance::getClassTypeId())) {
00596         QString unit = Base::UnitsApi::getPrefUnitOf(Base::Length);
00597         unit.prepend(QLatin1String(" "));
00598         sb->setSuffix(unit);
00599     }
00600     else if (prop.front()->getTypeId().isDerivedFrom(App::PropertyLength::getClassTypeId())) {
00601         sb->setMinimum(0.0);
00602         QString unit = Base::UnitsApi::getPrefUnitOf(Base::Length);
00603         unit.prepend(QLatin1String(" "));
00604         sb->setSuffix(unit);
00605     }
00606     else if (prop.front()->getTypeId().isDerivedFrom(App::PropertySpeed::getClassTypeId())) {
00607         //sb->setMinimum(0.0);
00608         //QString unit = Base::UnitsApi::getPrefUnitOf(Base::Acceleration);
00609         //unit.prepend(QLatin1String(" "));
00610         //sb->setSuffix(unit);
00611     }
00612     else if (prop.front()->getTypeId().isDerivedFrom(App::PropertyAcceleration::getClassTypeId())) {
00613         sb->setMinimum(0.0);
00614         QString unit = Base::UnitsApi::getPrefUnitOf(Base::Acceleration);
00615         unit.prepend(QLatin1String(" "));
00616         sb->setSuffix(unit);
00617     }
00618 }
00619 
00620 QVariant PropertyFloatItem::editorData(QWidget *editor) const
00621 {
00622     QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(editor);
00623     return QVariant(sb->value());
00624 }
00625 
00626 // --------------------------------------------------------------------
00627 
00628 
00629 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyUnitItem, Gui::PropertyEditor::PropertyItem);
00630 
00631 PropertyUnitItem::PropertyUnitItem()
00632 {
00633 }
00634 
00635 QVariant PropertyUnitItem::value(const App::Property* prop) const
00636 {
00637     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyLength::getClassTypeId()));
00638     //UnitType = Base::Length;
00639 
00640     double value = static_cast<const App::PropertyLength*>(prop)->getValue();
00641     QString nbr;
00642     nbr = Base::UnitsApi::toStrWithUserPrefs(Base::Length,value);
00643 
00644     return QVariant(nbr);
00645 }
00646 
00647 void PropertyUnitItem::setValue(const QVariant& value)
00648 {
00649     if (!value.canConvert(QVariant::String))
00650         return;
00651     QString val = value.toString();
00652     QString data = QString::fromAscii("\"%1\"").arg(val);
00653     setPropertyValue(data);
00654 }
00655 
00656 QWidget* PropertyUnitItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00657 {
00658     QLineEdit *le = new QLineEdit(parent);
00659     le->setFrame(false);
00660     QObject::connect(le, SIGNAL(textChanged(const QString&)), receiver, method);
00661     return le;
00662 }
00663 
00664 void PropertyUnitItem::setEditorData(QWidget *editor, const QVariant& data) const
00665 {
00666     QLineEdit *le = qobject_cast<QLineEdit*>(editor);
00667     le->setText(data.toString());
00668 }
00669 
00670 QVariant PropertyUnitItem::editorData(QWidget *editor) const
00671 {
00672     QLineEdit *le = qobject_cast<QLineEdit*>(editor);
00673     return QVariant(le->text());
00674 }
00675 
00676 // --------------------------------------------------------------------
00677 
00678 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyFloatConstraintItem, Gui::PropertyEditor::PropertyItem);
00679 
00680 PropertyFloatConstraintItem::PropertyFloatConstraintItem()
00681 {
00682 }
00683 
00684 QVariant PropertyFloatConstraintItem::toString(const QVariant& prop) const
00685 {
00686     double value = prop.toDouble();
00687     QString data = QLocale::system().toString(value, 'f', 2);
00688     return QVariant(data);
00689 }
00690 
00691 QVariant PropertyFloatConstraintItem::value(const App::Property* prop) const
00692 {
00693     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyFloatConstraint::getClassTypeId()));
00694 
00695     double value = static_cast<const App::PropertyFloatConstraint*>(prop)->getValue();
00696     return QVariant(value);
00697 }
00698 
00699 void PropertyFloatConstraintItem::setValue(const QVariant& value)
00700 {
00701     if (!value.canConvert(QVariant::Double))
00702         return;
00703     double val = value.toDouble();
00704     QString data = QString::fromAscii("%1").arg(val,0,'f',2);
00705     setPropertyValue(data);
00706 }
00707 
00708 QWidget* PropertyFloatConstraintItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00709 {
00710     QDoubleSpinBox *sb = new QDoubleSpinBox(parent);
00711     sb->setFrame(false);
00712     QObject::connect(sb, SIGNAL(valueChanged(double)), receiver, method);
00713     return sb;
00714 }
00715 
00716 void PropertyFloatConstraintItem::setEditorData(QWidget *editor, const QVariant& /*data*/) const
00717 {
00718     const std::vector<App::Property*>& items = getPropertyData();
00719     App::PropertyFloatConstraint* prop = (App::PropertyFloatConstraint*)items[0];
00720 
00721     const App::PropertyFloatConstraint::Constraints* c = ((App::PropertyFloatConstraint*)prop)->getConstraints();
00722     QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(editor);
00723     if (c) {
00724         sb->setMinimum(c->LowerBound);
00725         sb->setMaximum(c->UpperBound);
00726         sb->setSingleStep(c->StepSize);
00727     }
00728     else {
00729         sb->setMinimum((double)INT_MIN);
00730         sb->setMaximum((double)INT_MAX);
00731         sb->setSingleStep(0.1);
00732     }
00733     sb->setValue(prop->getValue());
00734 }
00735 
00736 QVariant PropertyFloatConstraintItem::editorData(QWidget *editor) const
00737 {
00738     QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(editor);
00739     return QVariant(sb->value());
00740 }
00741 
00742 // --------------------------------------------------------------------
00743 
00744 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyAngleItem, Gui::PropertyEditor::PropertyFloatItem);
00745 
00746 PropertyAngleItem::PropertyAngleItem()
00747 {
00748 }
00749 
00750 void PropertyAngleItem::setEditorData(QWidget *editor, const QVariant& data) const
00751 {
00752     const App::PropertyFloatConstraint::Constraints* c = 0;
00753     const std::vector<App::Property*>& items = getPropertyData();
00754     if (!items.empty()) {
00755         App::PropertyAngle* prop = static_cast<App::PropertyAngle*>(items[0]);
00756         c = prop->getConstraints();
00757     }
00758 
00759     QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox*>(editor);
00760     if (c) {
00761         sb->setMinimum(c->LowerBound);
00762         sb->setMaximum(c->UpperBound);
00763         sb->setSingleStep(c->StepSize);
00764     }
00765     else {
00766         sb->setMinimum((double)INT_MIN);
00767         sb->setMaximum((double)INT_MAX);
00768         sb->setSingleStep(1.0);
00769     }
00770 
00771     sb->setValue(data.toDouble());
00772     sb->setSuffix(QString::fromUtf8(" \xc2\xb0"));
00773 }
00774 
00775 QVariant PropertyAngleItem::toString(const QVariant& prop) const
00776 {
00777     double value = prop.toDouble();
00778     QString data = QString::fromUtf8("%1 \xc2\xb0")
00779         .arg(QLocale::system().toString(value, 'f', 2));
00780     return QVariant(data);
00781 }
00782 
00783 // --------------------------------------------------------------------
00784 
00785 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyBoolItem, Gui::PropertyEditor::PropertyItem);
00786 
00787 PropertyBoolItem::PropertyBoolItem()
00788 {
00789 }
00790 
00791 QVariant PropertyBoolItem::value(const App::Property* prop) const
00792 {
00793     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyBool::getClassTypeId()));
00794     
00795     bool value = ((App::PropertyBool*)prop)->getValue();
00796     return QVariant(value);
00797 }
00798 
00799 void PropertyBoolItem::setValue(const QVariant& value)
00800 {
00801     if (!value.canConvert(QVariant::Bool))
00802         return;
00803     bool val = value.toBool();
00804     QString data = (val ? QLatin1String("True") : QLatin1String("False"));
00805     setPropertyValue(data);
00806 }
00807 
00808 QWidget* PropertyBoolItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
00809 {
00810     QComboBox *cb = new QComboBox(parent);
00811     cb->setFrame(false);
00812     cb->addItem(QLatin1String("false"));
00813     cb->addItem(QLatin1String("true"));
00814     QObject::connect(cb, SIGNAL(activated(int)), receiver, method);
00815     return cb;
00816 }
00817 
00818 void PropertyBoolItem::setEditorData(QWidget *editor, const QVariant& data) const
00819 {
00820     QComboBox *cb = qobject_cast<QComboBox*>(editor);
00821     cb->setCurrentIndex(cb->findText(data.toString()));
00822 }
00823 
00824 QVariant PropertyBoolItem::editorData(QWidget *editor) const
00825 {
00826     QComboBox *cb = qobject_cast<QComboBox*>(editor);
00827     return QVariant(cb->currentText());
00828 }
00829 
00830 // ---------------------------------------------------------------
00831 
00832 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyVectorItem, Gui::PropertyEditor::PropertyItem);
00833 
00834 PropertyVectorItem::PropertyVectorItem()
00835 {
00836     m_x = static_cast<PropertyFloatItem*>(PropertyFloatItem::create());
00837     m_x->setParent(this);
00838     m_x->setPropertyName(QLatin1String("x"));
00839     this->appendChild(m_x);
00840     m_y = static_cast<PropertyFloatItem*>(PropertyFloatItem::create());
00841     m_y->setParent(this);
00842     m_y->setPropertyName(QLatin1String("y"));
00843     this->appendChild(m_y);
00844     m_z = static_cast<PropertyFloatItem*>(PropertyFloatItem::create());
00845     m_z->setParent(this);
00846     m_z->setPropertyName(QLatin1String("z"));
00847     this->appendChild(m_z);
00848 }
00849 
00850 QVariant PropertyVectorItem::toString(const QVariant& prop) const
00851 {
00852     const Base::Vector3f& value = prop.value<Base::Vector3f>();
00853     QString data = QString::fromAscii("[%1 %2 %3]")
00854         .arg(QLocale::system().toString(value.x, 'f', 2))
00855         .arg(QLocale::system().toString(value.y, 'f', 2))
00856         .arg(QLocale::system().toString(value.z, 'f', 2));
00857     return QVariant(data);
00858 }
00859 
00860 QVariant PropertyVectorItem::value(const App::Property* prop) const
00861 {
00862     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyVector::getClassTypeId()));
00863 
00864     const Base::Vector3f& value = static_cast<const App::PropertyVector*>(prop)->getValue();
00865     return QVariant::fromValue<Base::Vector3f>(value);
00866 }
00867 
00868 void PropertyVectorItem::setValue(const QVariant& value)
00869 {
00870     if (!value.canConvert<Base::Vector3f>())
00871         return;
00872     const Base::Vector3f& val = value.value<Base::Vector3f>();
00873     QString data = QString::fromAscii("(%1, %2, %3)")
00874                     .arg(val.x,0,'f',2)
00875                     .arg(val.y,0,'f',2)
00876                     .arg(val.z,0,'f',2);
00877     setPropertyValue(data);
00878 }
00879 
00880 QWidget* PropertyVectorItem::createEditor(QWidget* parent, const QObject* /*receiver*/, const char* /*method*/) const
00881 {
00882     QLineEdit *le = new QLineEdit(parent);
00883     le->setFrame(false);
00884     le->setReadOnly(true);
00885     return le;
00886 }
00887 
00888 void PropertyVectorItem::setEditorData(QWidget *editor, const QVariant& data) const
00889 {
00890     QLineEdit* le = qobject_cast<QLineEdit*>(editor);
00891     const Base::Vector3f& value = data.value<Base::Vector3f>();
00892     QString text = QString::fromAscii("[%1 %2 %3]")
00893         .arg(QLocale::system().toString(value.x, 'f', 2))
00894         .arg(QLocale::system().toString(value.y, 'f', 2))
00895         .arg(QLocale::system().toString(value.z, 'f', 2));
00896     le->setText(text);
00897 }
00898 
00899 QVariant PropertyVectorItem::editorData(QWidget *editor) const
00900 {
00901     QLineEdit *le = qobject_cast<QLineEdit*>(editor);
00902     return QVariant(le->text());
00903 }
00904 
00905 double PropertyVectorItem::x() const
00906 {
00907     return data(1,Qt::EditRole).value<Base::Vector3f>().x;
00908 }
00909 
00910 void PropertyVectorItem::setX(double x)
00911 {
00912     setData(QVariant::fromValue(Base::Vector3f(x, y(), z())));
00913 }
00914 
00915 double PropertyVectorItem::y() const
00916 {
00917     return data(1,Qt::EditRole).value<Base::Vector3f>().y;
00918 }
00919 
00920 void PropertyVectorItem::setY(double y)
00921 {
00922     setData(QVariant::fromValue(Base::Vector3f(x(), y, z())));
00923 }
00924 
00925 double PropertyVectorItem::z() const
00926 {
00927     return data(1,Qt::EditRole).value<Base::Vector3f>().z;
00928 }
00929 
00930 void PropertyVectorItem::setZ(double z)
00931 {
00932     setData(QVariant::fromValue(Base::Vector3f(x(), y(), z)));
00933 }
00934 
00935 // ---------------------------------------------------------------
00936 
00937 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyDoubleVectorItem, Gui::PropertyEditor::PropertyItem);
00938 
00939 PropertyDoubleVectorItem::PropertyDoubleVectorItem()
00940 {
00941     m_x = static_cast<PropertyFloatItem*>(PropertyFloatItem::create());
00942     m_x->setParent(this);
00943     m_x->setPropertyName(QLatin1String("x"));
00944     this->appendChild(m_x);
00945     m_y = static_cast<PropertyFloatItem*>(PropertyFloatItem::create());
00946     m_y->setParent(this);
00947     m_y->setPropertyName(QLatin1String("y"));
00948     this->appendChild(m_y);
00949     m_z = static_cast<PropertyFloatItem*>(PropertyFloatItem::create());
00950     m_z->setParent(this);
00951     m_z->setPropertyName(QLatin1String("z"));
00952     this->appendChild(m_z);
00953 }
00954 
00955 QVariant PropertyDoubleVectorItem::toString(const QVariant& prop) const
00956 {
00957     const Base::Vector3d& value = prop.value<Base::Vector3d>();
00958     QString data = QString::fromAscii("[%1 %2 %3]")
00959         .arg(QLocale::system().toString(value.x, 'f', 2))
00960         .arg(QLocale::system().toString(value.y, 'f', 2))
00961         .arg(QLocale::system().toString(value.z, 'f', 2));
00962     return QVariant(data);
00963 }
00964 
00965 QVariant PropertyDoubleVectorItem::value(const App::Property* prop) const
00966 {
00967     // no real property class is using this
00968     return QVariant::fromValue<Base::Vector3d>(Base::Vector3d());
00969 }
00970 
00971 void PropertyDoubleVectorItem::setValue(const QVariant& value)
00972 {
00973     if (!value.canConvert<Base::Vector3d>())
00974         return;
00975     const Base::Vector3d& val = value.value<Base::Vector3d>();
00976     QString data = QString::fromAscii("(%1, %2, %3)")
00977                     .arg(val.x,0,'f',2)
00978                     .arg(val.y,0,'f',2)
00979                     .arg(val.z,0,'f',2);
00980     setPropertyValue(data);
00981 }
00982 
00983 QWidget* PropertyDoubleVectorItem::createEditor(QWidget* parent, const QObject* /*receiver*/, const char* /*method*/) const
00984 {
00985     QLineEdit *le = new QLineEdit(parent);
00986     le->setFrame(false);
00987     le->setReadOnly(true);
00988     return le;
00989 }
00990 
00991 void PropertyDoubleVectorItem::setEditorData(QWidget *editor, const QVariant& data) const
00992 {
00993     QLineEdit* le = qobject_cast<QLineEdit*>(editor);
00994     const Base::Vector3d& value = data.value<Base::Vector3d>();
00995     QString text = QString::fromAscii("[%1 %2 %3]")
00996         .arg(QLocale::system().toString(value.x, 'f', 2))
00997         .arg(QLocale::system().toString(value.y, 'f', 2))
00998         .arg(QLocale::system().toString(value.z, 'f', 2));
00999     le->setText(text);
01000 }
01001 
01002 QVariant PropertyDoubleVectorItem::editorData(QWidget *editor) const
01003 {
01004     QLineEdit *le = qobject_cast<QLineEdit*>(editor);
01005     return QVariant(le->text());
01006 }
01007 
01008 double PropertyDoubleVectorItem::x() const
01009 {
01010     return data(1,Qt::EditRole).value<Base::Vector3d>().x;
01011 }
01012 
01013 void PropertyDoubleVectorItem::setX(double x)
01014 {
01015     setData(QVariant::fromValue(Base::Vector3d(x, y(), z())));
01016 }
01017 
01018 double PropertyDoubleVectorItem::y() const
01019 {
01020     return data(1,Qt::EditRole).value<Base::Vector3d>().y;
01021 }
01022 
01023 void PropertyDoubleVectorItem::setY(double y)
01024 {
01025     setData(QVariant::fromValue(Base::Vector3d(x(), y, z())));
01026 }
01027 
01028 double PropertyDoubleVectorItem::z() const
01029 {
01030     return data(1,Qt::EditRole).value<Base::Vector3d>().z;
01031 }
01032 
01033 void PropertyDoubleVectorItem::setZ(double z)
01034 {
01035     setData(QVariant::fromValue(Base::Vector3d(x(), y(), z)));
01036 }
01037 
01038 // --------------------------------------------------------------------
01039 
01040 PlacementEditor::PlacementEditor(const QString& name, QWidget * parent)
01041     : LabelButton(parent), _task(0)
01042 {
01043     propertyname = name;
01044     propertyname.replace(QLatin1String(" "), QLatin1String(""));
01045 }
01046 
01047 PlacementEditor::~PlacementEditor()
01048 {
01049 }
01050 
01051 void PlacementEditor::browse()
01052 {
01053     Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
01054     Gui::Dialog::TaskPlacement* task;
01055     task = qobject_cast<Gui::Dialog::TaskPlacement*>(dlg);
01056     if (dlg && !task) {
01057         // there is already another task dialog which must be closed first
01058         Gui::Control().showDialog(dlg);
01059         return;
01060     }
01061     if (!task) {
01062         task = new Gui::Dialog::TaskPlacement();
01063     }
01064     if (!_task) {
01065         _task = task;
01066         connect(task, SIGNAL(placementChanged(const QVariant &, bool, bool)),
01067                 this, SLOT(updateValue(const QVariant&, bool, bool)));
01068     }
01069     task->setPlacement(value().value<Base::Placement>());
01070     task->setPropertyName(propertyname);
01071     Gui::Control().showDialog(task);
01072 }
01073 
01074 void PlacementEditor::showValue(const QVariant& d)
01075 {
01076     const Base::Placement& p = d.value<Base::Placement>();
01077     double angle;
01078     Base::Vector3d dir, pos;
01079     p.getRotation().getValue(dir, angle);
01080     pos = p.getPosition();
01081     QString data = QString::fromAscii("[(%1 %2 %3);%4;(%5 %6 %7)]")
01082                     .arg(QLocale::system().toString(dir.x,'f',2))
01083                     .arg(QLocale::system().toString(dir.y,'f',2))
01084                     .arg(QLocale::system().toString(dir.z,'f',2))
01085                     .arg(QLocale::system().toString(angle,'f',2))
01086                     .arg(QLocale::system().toString(pos.x,'f',2))
01087                     .arg(QLocale::system().toString(pos.y,'f',2))
01088                     .arg(QLocale::system().toString(pos.z,'f',2));
01089     getLabel()->setText(data);
01090 }
01091 
01092 void PlacementEditor::updateValue(const QVariant& v, bool incr, bool data)
01093 {
01094     if (data) {
01095         if (incr) {
01096             QVariant u = value();
01097             const Base::Placement& plm = u.value<Base::Placement>();
01098             const Base::Placement& rel = v.value<Base::Placement>();
01099             Base::Placement data = rel * plm;
01100             setValue(QVariant::fromValue<Base::Placement>(data));
01101         }
01102         else {
01103             setValue(v);
01104         }
01105     }
01106 }
01107 
01108 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyPlacementItem, Gui::PropertyEditor::PropertyItem);
01109 
01110 PropertyPlacementItem::PropertyPlacementItem() : init_axis(false), changed_value(false), rot_axis(0,0,1)
01111 {
01112     m_a = static_cast<PropertyAngleItem*>(PropertyAngleItem::create());
01113     m_a->setParent(this);
01114     m_a->setPropertyName(QLatin1String("Angle"));
01115     this->appendChild(m_a);
01116     m_d = static_cast<PropertyDoubleVectorItem*>(PropertyDoubleVectorItem::create());
01117     m_d->setParent(this);
01118     m_d->setPropertyName(QLatin1String("Axis"));
01119     m_d->setReadOnly(true);
01120     this->appendChild(m_d);
01121     m_p = static_cast<PropertyDoubleVectorItem*>(PropertyDoubleVectorItem::create());
01122     m_p->setParent(this);
01123     m_p->setPropertyName(QLatin1String("Position"));
01124     m_p->setReadOnly(true);
01125     this->appendChild(m_p);
01126 }
01127 
01128 PropertyPlacementItem::~PropertyPlacementItem()
01129 {
01130 }
01131 
01132 double PropertyPlacementItem::getAngle() const
01133 {
01134     QVariant value = data(1, Qt::EditRole);
01135     if (!value.canConvert<Base::Placement>())
01136         return 0.0;
01137     const Base::Placement& val = value.value<Base::Placement>();
01138     double angle;
01139     Base::Vector3d dir;
01140     val.getRotation().getValue(dir, angle);
01141     if (dir * this->rot_axis < 0.0)
01142         angle = -angle;
01143     return Base::toDegrees<double>(angle);
01144 }
01145 
01146 void PropertyPlacementItem::setAngle(double angle)
01147 {
01148     QVariant value = data(1, Qt::EditRole);
01149     if (!value.canConvert<Base::Placement>())
01150         return;
01151 
01152     Base::Placement val = value.value<Base::Placement>();
01153     Base::Rotation rot;
01154     rot.setValue(this->rot_axis, Base::toRadians<double>(angle));
01155     val.setRotation(rot);
01156     changed_value = true;
01157     setValue(QVariant::fromValue(val));
01158 }
01159 
01160 Base::Vector3d PropertyPlacementItem::getAxis() const
01161 {
01162     // We must store the rotation axis in a member because
01163     // if we read the value from the property we would always
01164     // get a normalized vector which makes it quite unhandy
01165     // to work with
01166     return this->rot_axis;
01167 }
01168 
01169 void PropertyPlacementItem::setAxis(const Base::Vector3d& axis)
01170 {
01171     QVariant value = data(1, Qt::EditRole);
01172     if (!value.canConvert<Base::Placement>())
01173         return;
01174     this->rot_axis = axis;
01175     Base::Placement val = value.value<Base::Placement>();
01176     Base::Rotation rot = val.getRotation();
01177     Base::Vector3d dummy; double angle;
01178     rot.getValue(dummy, angle);
01179     if (dummy * axis < 0.0)
01180         angle = -angle;
01181     rot.setValue(axis, angle);
01182     val.setRotation(rot);
01183     changed_value = true;
01184     setValue(QVariant::fromValue(val));
01185 }
01186 
01187 Base::Vector3d PropertyPlacementItem::getPosition() const
01188 {
01189     QVariant value = data(1, Qt::EditRole);
01190     if (!value.canConvert<Base::Placement>())
01191         return Base::Vector3d(0,0,0);
01192     const Base::Placement& val = value.value<Base::Placement>();
01193     return val.getPosition();
01194 }
01195 
01196 void PropertyPlacementItem::setPosition(const Base::Vector3d& pos)
01197 {
01198     QVariant value = data(1, Qt::EditRole);
01199     if (!value.canConvert<Base::Placement>())
01200         return;
01201     Base::Placement val = value.value<Base::Placement>();
01202     val.setPosition(pos);
01203     changed_value = true;
01204     setValue(QVariant::fromValue(val));
01205 }
01206 
01207 QVariant PropertyPlacementItem::value(const App::Property* prop) const
01208 {
01209     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyPlacement::getClassTypeId()));
01210 
01211     const Base::Placement& value = static_cast<const App::PropertyPlacement*>(prop)->getValue();
01212     double angle;
01213     Base::Vector3d dir;
01214     value.getRotation().getValue(dir, angle);
01215     if (!init_axis) {
01216         const_cast<PropertyPlacementItem*>(this)->rot_axis = dir;
01217         const_cast<PropertyPlacementItem*>(this)->init_axis = true;
01218     }
01219     return QVariant::fromValue<Base::Placement>(value);
01220 }
01221 
01222 QVariant PropertyPlacementItem::toolTip(const App::Property* prop) const
01223 {
01224     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyPlacement::getClassTypeId()));
01225 
01226     const Base::Placement& p = static_cast<const App::PropertyPlacement*>(prop)->getValue();
01227     double angle;
01228     Base::Vector3d dir, pos;
01229     p.getRotation().getValue(dir, angle);
01230     pos = p.getPosition();
01231     QString data = QString::fromAscii("Axis: (%1 %2 %3)\n"
01232                                       "Angle: %4\n"
01233                                       "Move: (%5 %6 %7)")
01234                     .arg(QLocale::system().toString(dir.x,'f',2))
01235                     .arg(QLocale::system().toString(dir.y,'f',2))
01236                     .arg(QLocale::system().toString(dir.z,'f',2))
01237                     .arg(QLocale::system().toString(angle,'f',2))
01238                     .arg(QLocale::system().toString(pos.x,'f',2))
01239                     .arg(QLocale::system().toString(pos.y,'f',2))
01240                     .arg(QLocale::system().toString(pos.z,'f',2));
01241     return QVariant(data);
01242 }
01243 
01244 QVariant PropertyPlacementItem::toString(const QVariant& prop) const
01245 {
01246     const Base::Placement& p = prop.value<Base::Placement>();
01247     double angle;
01248     Base::Vector3d dir, pos;
01249     p.getRotation().getValue(dir, angle);
01250     pos = p.getPosition();
01251     QString data = QString::fromAscii("[(%1 %2 %3);%4;(%5 %6 %7)]")
01252                     .arg(QLocale::system().toString(dir.x,'f',2))
01253                     .arg(QLocale::system().toString(dir.y,'f',2))
01254                     .arg(QLocale::system().toString(dir.z,'f',2))
01255                     .arg(QLocale::system().toString(angle,'f',2))
01256                     .arg(QLocale::system().toString(pos.x,'f',2))
01257                     .arg(QLocale::system().toString(pos.y,'f',2))
01258                     .arg(QLocale::system().toString(pos.z,'f',2));
01259     return QVariant(data);
01260 }
01261 
01262 void PropertyPlacementItem::setValue(const QVariant& value)
01263 {
01264     if (!value.canConvert<Base::Placement>())
01265         return;
01266     // Accept this only if the user changed the axis, angle or position but
01267     // not if >this< item looses focus
01268     if (!changed_value)
01269         return;
01270     changed_value = false;
01271     const Base::Placement& val = value.value<Base::Placement>();
01272     Base::Vector3d pos = val.getPosition();
01273     const Base::Rotation& rt = val.getRotation();
01274     QString data = QString::fromAscii("App.Placement("
01275                                       "App.Vector(%1,%2,%3),"
01276                                       "App.Rotation(%4,%5,%6,%7))")
01277                     .arg(pos.x,0,'g',6)
01278                     .arg(pos.y,0,'g',6)
01279                     .arg(pos.z,0,'g',6)
01280                     .arg(rt[0],0,'g',6)
01281                     .arg(rt[1],0,'g',6)
01282                     .arg(rt[2],0,'g',6)
01283                     .arg(rt[3],0,'g',6);
01284     setPropertyValue(data);
01285 }
01286 
01287 QWidget* PropertyPlacementItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
01288 {
01289     PlacementEditor *pe = new PlacementEditor(this->propertyName(), parent);
01290     QObject::connect(pe, SIGNAL(valueChanged(const QVariant &)), receiver, method);
01291     return pe;
01292 }
01293 
01294 void PropertyPlacementItem::setEditorData(QWidget *editor, const QVariant& data) const
01295 {
01296     Gui::LabelButton *pe = qobject_cast<Gui::LabelButton*>(editor);
01297     pe->setValue(data);
01298 }
01299 
01300 QVariant PropertyPlacementItem::editorData(QWidget *editor) const
01301 {
01302     Gui::LabelButton *pe = qobject_cast<Gui::LabelButton*>(editor);
01303     return pe->value();
01304 }
01305 
01306 // ---------------------------------------------------------------
01307 
01308 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyEnumItem, Gui::PropertyEditor::PropertyItem);
01309 
01310 PropertyEnumItem::PropertyEnumItem()
01311 {
01312 }
01313 
01314 QVariant PropertyEnumItem::value(const App::Property* prop) const
01315 {
01316     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyEnumeration::getClassTypeId()));
01317 
01318     const App::PropertyEnumeration* prop_enum = static_cast<const App::PropertyEnumeration*>(prop);
01319     if (prop_enum->getEnums() == 0) {
01320         return QVariant(QString());
01321     }
01322     else {
01323         const std::vector<std::string>& value = prop_enum->getEnumVector();
01324         long currentItem = prop_enum->getValue();
01325         return QVariant(QString::fromUtf8(value[currentItem].c_str()));
01326     }
01327 }
01328 
01329 void PropertyEnumItem::setValue(const QVariant& value)
01330 {
01331     if (!value.canConvert(QVariant::StringList))
01332         return;
01333     QStringList items = value.toStringList();
01334     if (!items.isEmpty()) {
01335         QString val = items.front();
01336         QString data = QString::fromAscii("\"%1\"").arg(val);
01337         setPropertyValue(data);
01338     }
01339 }
01340 
01341 QWidget* PropertyEnumItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
01342 {
01343     QComboBox *cb = new QComboBox(parent);
01344     cb->setFrame(false);
01345     QObject::connect(cb, SIGNAL(activated(int)), receiver, method);
01346     return cb;
01347 }
01348 
01349 void PropertyEnumItem::setEditorData(QWidget *editor, const QVariant& data) const
01350 {
01351     const std::vector<App::Property*>& items = getPropertyData();
01352 
01353     QStringList commonModes, modes;
01354     for (std::vector<App::Property*>::const_iterator it = items.begin(); it != items.end(); ++it) {
01355         if ((*it)->getTypeId() == App::PropertyEnumeration::getClassTypeId()) {
01356             App::PropertyEnumeration* prop = static_cast<App::PropertyEnumeration*>(*it);
01357             if (prop->getEnums() == 0) {
01358                 commonModes.clear();
01359                 break;
01360             }
01361             const std::vector<std::string>& value = prop->getEnumVector();
01362             if (it == items.begin()) {
01363                 for (std::vector<std::string>::const_iterator jt = value.begin(); jt != value.end(); ++jt)
01364                     commonModes << QLatin1String(jt->c_str());
01365             }
01366             else {
01367                 for (std::vector<std::string>::const_iterator jt = value.begin(); jt != value.end(); ++jt) {
01368                     if (commonModes.contains(QLatin1String(jt->c_str())))
01369                         modes << QLatin1String(jt->c_str());
01370                 }
01371 
01372                 commonModes = modes;
01373                 modes.clear();
01374             }
01375         }
01376     }
01377 
01378     QComboBox *cb = qobject_cast<QComboBox*>(editor);
01379     if (!commonModes.isEmpty()) {
01380         cb->addItems(commonModes);
01381         cb->setCurrentIndex(cb->findText(data.toString()));
01382     }
01383 }
01384 
01385 QVariant PropertyEnumItem::editorData(QWidget *editor) const
01386 {
01387     QComboBox *cb = qobject_cast<QComboBox*>(editor);
01388     return QVariant(cb->currentText());
01389 }
01390 
01391 // ---------------------------------------------------------------
01392 
01393 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyStringListItem, Gui::PropertyEditor::PropertyItem);
01394 
01395 PropertyStringListItem::PropertyStringListItem()
01396 {
01397 }
01398 
01399 QWidget* PropertyStringListItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
01400 {
01401     Gui::LabelEditor* le = new Gui::LabelEditor(parent);
01402     le->setAutoFillBackground(true);
01403     QObject::connect(le, SIGNAL(textChanged(const QString&)), receiver, method);
01404     return le;
01405 }
01406 
01407 void PropertyStringListItem::setEditorData(QWidget *editor, const QVariant& data) const
01408 {
01409     Gui::LabelEditor *le = qobject_cast<Gui::LabelEditor*>(editor);
01410     QStringList list = data.toStringList();
01411     le->setText(list.join(QChar::fromAscii('\n')));
01412 }
01413 
01414 QVariant PropertyStringListItem::editorData(QWidget *editor) const
01415 {
01416     Gui::LabelEditor *le = qobject_cast<Gui::LabelEditor*>(editor);
01417     QString complete = le->text();
01418     QStringList list = complete.split(QChar::fromAscii('\n'));
01419     return QVariant(list);
01420 }
01421 
01422 QVariant PropertyStringListItem::toString(const QVariant& prop) const
01423 {
01424     QStringList list = prop.toStringList();
01425     QString text = QString::fromUtf8("[%1]").arg(list.join(QLatin1String(",")));
01426 
01427     return QVariant(text);
01428 }
01429 
01430 QVariant PropertyStringListItem::value(const App::Property* prop) const
01431 {
01432     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyStringList::getClassTypeId()));
01433 
01434     QStringList list;
01435     const std::vector<std::string>& value = ((App::PropertyStringList*)prop)->getValues();
01436     for ( std::vector<std::string>::const_iterator jt = value.begin(); jt != value.end(); ++jt ) {
01437         list << QString::fromUtf8(jt->c_str());
01438     }
01439 
01440     return QVariant(list);
01441 }
01442 
01443 void PropertyStringListItem::setValue(const QVariant& value)
01444 {
01445     if (!value.canConvert(QVariant::StringList))
01446         return;
01447     QStringList values = value.toStringList();
01448     QString data;
01449     QTextStream str(&data);
01450     str << "[";
01451     for (QStringList::Iterator it = values.begin(); it != values.end(); ++it) {
01452         str << "unicode('" << *it << "', 'utf-8'),";
01453     }
01454     str << "]";
01455     setPropertyValue(data);
01456 }
01457 
01458 // --------------------------------------------------------------------
01459 
01460 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyColorItem, Gui::PropertyEditor::PropertyItem);
01461 
01462 PropertyColorItem::PropertyColorItem()
01463 {
01464 }
01465 
01466 QVariant PropertyColorItem::decoration(const App::Property* prop) const
01467 {
01468     App::Color value = ((App::PropertyColor*)prop)->getValue();
01469     QColor color((int)(255.0f*value.r),(int)(255.0f*value.g),(int)(255.0f*value.b));
01470 
01471     int size = QApplication::style()->pixelMetric(QStyle::PM_ListViewIconSize);
01472     QPixmap p(size, size);
01473     p.fill(color);
01474 
01475     return QVariant(p);
01476 }
01477 
01478 QVariant PropertyColorItem::toString(const QVariant& prop) const
01479 {
01480     QColor value = prop.value<QColor>();
01481     QString color = QString::fromAscii("[%1, %2, %3]")
01482         .arg(value.red()).arg(value.green()).arg(value.blue());
01483     return QVariant(color);
01484 }
01485 
01486 QVariant PropertyColorItem::value(const App::Property* prop) const
01487 {
01488     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyColor::getClassTypeId()));
01489 
01490     App::Color value = ((App::PropertyColor*)prop)->getValue();
01491     return QVariant(QColor((int)(255.0f*value.r),(int)(255.0f*value.g),(int)(255.0f*value.b)));
01492 }
01493 
01494 void PropertyColorItem::setValue(const QVariant& value)
01495 {
01496     if (!value.canConvert<QColor>())
01497         return;
01498     QColor col = value.value<QColor>();
01499     App::Color val;
01500     val.r = (float)col.red()/255.0f;
01501     val.g = (float)col.green()/255.0f;
01502     val.b = (float)col.blue()/255.0f;
01503     QString data = QString::fromAscii("(%1,%2,%3)")
01504                     .arg(val.r,0,'f',2)
01505                     .arg(val.g,0,'f',2)
01506                     .arg(val.b,0,'f',2);
01507     setPropertyValue(data);
01508 }
01509 
01510 QWidget* PropertyColorItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
01511 {
01512     Gui::ColorButton* cb = new Gui::ColorButton( parent );
01513     QObject::connect(cb, SIGNAL(changed()), receiver, method);
01514     return cb;
01515 }
01516 
01517 void PropertyColorItem::setEditorData(QWidget *editor, const QVariant& data) const
01518 {
01519     Gui::ColorButton *cb = qobject_cast<Gui::ColorButton*>(editor);
01520     QColor color = data.value<QColor>();
01521     cb->setColor(color);
01522 }
01523 
01524 QVariant PropertyColorItem::editorData(QWidget *editor) const
01525 {
01526     Gui::ColorButton *cb = qobject_cast<Gui::ColorButton*>(editor);
01527     QVariant var;
01528     var.setValue(cb->color());
01529     return var;
01530 }
01531 
01532 // --------------------------------------------------------------------
01533 
01534 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyFileItem, Gui::PropertyEditor::PropertyItem);
01535 
01536 PropertyFileItem::PropertyFileItem()
01537 {
01538 }
01539 
01540 QVariant PropertyFileItem::value(const App::Property* prop) const
01541 {
01542     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyFile::getClassTypeId()));
01543 
01544     std::string value = static_cast<const App::PropertyFile*>(prop)->getValue();
01545     return QVariant(QString::fromUtf8(value.c_str()));
01546 }
01547 
01548 void PropertyFileItem::setValue(const QVariant& value)
01549 {
01550     if (!value.canConvert(QVariant::String))
01551         return;
01552     QString val = value.toString();
01553     QString data = QString::fromAscii("\"%1\"").arg(val);
01554     setPropertyValue(data);
01555 }
01556 
01557 QVariant PropertyFileItem::toolTip(const App::Property* prop) const
01558 {
01559     return value(prop);
01560 }
01561 
01562 QWidget* PropertyFileItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
01563 {
01564     Gui::FileChooser *fc = new Gui::FileChooser(parent);
01565     fc->setAutoFillBackground(true);
01566     QObject::connect(fc, SIGNAL(fileNameSelected(const QString&)), receiver, method);
01567     return fc;
01568 }
01569 
01570 void PropertyFileItem::setEditorData(QWidget *editor, const QVariant& data) const
01571 {
01572     Gui::FileChooser *fc = qobject_cast<Gui::FileChooser*>(editor);
01573     fc->setFileName(data.toString());
01574 }
01575 
01576 QVariant PropertyFileItem::editorData(QWidget *editor) const
01577 {
01578     Gui::FileChooser *fc = qobject_cast<Gui::FileChooser*>(editor);
01579     return QVariant(fc->fileName());
01580 }
01581 
01582 // --------------------------------------------------------------------
01583 
01584 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyPathItem, Gui::PropertyEditor::PropertyItem);
01585 
01586 PropertyPathItem::PropertyPathItem()
01587 {
01588 }
01589 
01590 QVariant PropertyPathItem::value(const App::Property* prop) const
01591 {
01592     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyPath::getClassTypeId()));
01593 
01594     std::string value = static_cast<const App::PropertyPath*>(prop)->getValue().string();
01595     return QVariant(QString::fromUtf8(value.c_str()));
01596 }
01597 
01598 void PropertyPathItem::setValue(const QVariant& value)
01599 {
01600     if (!value.canConvert(QVariant::String))
01601         return;
01602     QString val = value.toString();
01603     QString data = QString::fromAscii("\"%1\"").arg(val);
01604     setPropertyValue(data);
01605 }
01606 
01607 QVariant PropertyPathItem::toolTip(const App::Property* prop) const
01608 {
01609     return value(prop);
01610 }
01611 
01612 QWidget* PropertyPathItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
01613 {
01614     Gui::FileChooser *fc = new Gui::FileChooser(parent);
01615     fc->setAutoFillBackground(true);
01616     QObject::connect(fc, SIGNAL(fileNameSelected(const QString&)), receiver, method);
01617     return fc;
01618 }
01619 
01620 void PropertyPathItem::setEditorData(QWidget *editor, const QVariant& data) const
01621 {
01622     Gui::FileChooser *fc = qobject_cast<Gui::FileChooser*>(editor);
01623     fc->setFileName(data.toString());
01624 }
01625 
01626 QVariant PropertyPathItem::editorData(QWidget *editor) const
01627 {
01628     Gui::FileChooser *fc = qobject_cast<Gui::FileChooser*>(editor);
01629     return QVariant(fc->fileName());
01630 }
01631 
01632 // --------------------------------------------------------------------
01633 
01634 TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyTransientFileItem, Gui::PropertyEditor::PropertyItem);
01635 
01636 PropertyTransientFileItem::PropertyTransientFileItem()
01637 {
01638 }
01639 
01640 QVariant PropertyTransientFileItem::value(const App::Property* prop) const
01641 {
01642     assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyFileIncluded::getClassTypeId()));
01643 
01644     std::string value = static_cast<const App::PropertyFileIncluded*>(prop)->getValue();
01645     return QVariant(QString::fromUtf8(value.c_str()));
01646 }
01647 
01648 void PropertyTransientFileItem::setValue(const QVariant& value)
01649 {
01650     if (!value.canConvert(QVariant::String))
01651         return;
01652     QString val = value.toString();
01653     QString data = QString::fromAscii("\"%1\"").arg(val);
01654     setPropertyValue(data);
01655 }
01656 
01657 QVariant PropertyTransientFileItem::toolTip(const App::Property* prop) const
01658 {
01659     return value(prop);
01660 }
01661 
01662 QWidget* PropertyTransientFileItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
01663 {
01664     Gui::FileChooser *fc = new Gui::FileChooser(parent);
01665     fc->setAutoFillBackground(true);
01666     QObject::connect(fc, SIGNAL(fileNameSelected(const QString&)), receiver, method);
01667     return fc;
01668 }
01669 
01670 void PropertyTransientFileItem::setEditorData(QWidget *editor, const QVariant& data) const
01671 {
01672     Gui::FileChooser *fc = qobject_cast<Gui::FileChooser*>(editor);
01673     fc->setFileName(data.toString());
01674 }
01675 
01676 QVariant PropertyTransientFileItem::editorData(QWidget *editor) const
01677 {
01678     Gui::FileChooser *fc = qobject_cast<Gui::FileChooser*>(editor);
01679     return QVariant(fc->fileName());
01680 }
01681 
01682 // --------------------------------------------------------------------
01683 
01684 PropertyItemEditorFactory::PropertyItemEditorFactory()
01685 {
01686 }
01687 
01688 PropertyItemEditorFactory::~PropertyItemEditorFactory()
01689 {
01690 }
01691 
01692 QWidget * PropertyItemEditorFactory::createEditor (QVariant::Type /*type*/, QWidget * /*parent*/) const
01693 {
01694     // do not allow to create any editor widgets because we do that in subclasses of PropertyItem
01695     return 0;
01696 }
01697 
01698 QByteArray PropertyItemEditorFactory::valuePropertyName (QVariant::Type /*type*/) const
01699 {
01700     // do not allow to set properties because we do that in subclasses of PropertyItem
01701     return "";
01702 }
01703 
01704 #include "moc_PropertyItem.cpp"
01705 

Generated on Wed Nov 23 19:00:31 2011 for FreeCAD by  doxygen 1.6.1