ViewProviderPythonFeature.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2006 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 <sstream>
00028 # include <QFileInfo>
00029 # include <QPixmap>
00030 # include <boost/signals.hpp>
00031 # include <boost/bind.hpp>
00032 # include <Inventor/nodes/SoDrawStyle.h>
00033 # include <Inventor/nodes/SoMaterial.h>
00034 # include <Inventor/nodes/SoSeparator.h>
00035 # include <Inventor/actions/SoSearchAction.h>
00036 # include <Inventor/draggers/SoDragger.h>
00037 # include <Inventor/manips/SoCenterballManip.h>
00038 # include <Inventor/nodes/SoBaseColor.h>
00039 # include <Inventor/nodes/SoCamera.h>
00040 # include <Inventor/nodes/SoDrawStyle.h>
00041 # include <Inventor/nodes/SoMaterial.h>
00042 # include <Inventor/nodes/SoSeparator.h>
00043 # include <Inventor/nodes/SoSwitch.h>
00044 # include <Inventor/nodes/SoDirectionalLight.h>
00045 # include <Inventor/sensors/SoNodeSensor.h> 
00046 # include <Inventor/SoPickedPoint.h>
00047 # include <Inventor/actions/SoRayPickAction.h> 
00048 #endif
00049 
00050 #include "ViewProviderPythonFeature.h"
00051 #include "ViewProviderPythonFeaturePy.h"
00052 #include "SoFCSelection.h"
00053 #include "SoFCBoundingBox.h"
00054 #include "Tree.h"
00055 #include "Window.h"
00056 #include "Application.h"
00057 #include "BitmapFactory.h"
00058 #include "Document.h"
00059 #include <App/DocumentObjectPy.h>
00060 #include <App/GeoFeature.h>
00061 #include <App/PropertyGeo.h>
00062 #include <Base/Console.h>
00063 #include <Base/Reader.h>
00064 #include <Base/Interpreter.h>
00065 
00066 
00067 using namespace Gui;
00068 
00069 namespace Gui {
00070 
00071 class ViewProviderPythonFeatureObserver
00072 {
00073 public:
00075     static ViewProviderPythonFeatureObserver* instance();
00077     static void destruct ();
00078     void slotAppendObject(const Gui::ViewProvider&);
00079     void slotDeleteObject(const Gui::ViewProvider&);
00080     void slotDeleteDocument(const Gui::Document&);
00081 
00082 private:
00083     static ViewProviderPythonFeatureObserver* _singleton;
00084 
00085     ViewProviderPythonFeatureObserver();
00086     ~ViewProviderPythonFeatureObserver();
00087     typedef std::map<
00088                 const App::DocumentObject*,
00089                 std::string
00090             > ObjectProxy;
00091 
00092     std::map<const App::Document*, ObjectProxy> proxyMap;
00093 };
00094 
00095 }
00096 
00097 ViewProviderPythonFeatureObserver* ViewProviderPythonFeatureObserver::_singleton = 0;
00098 
00099 ViewProviderPythonFeatureObserver* ViewProviderPythonFeatureObserver::instance()
00100 {
00101     if (!_singleton)
00102         _singleton = new ViewProviderPythonFeatureObserver;
00103     return _singleton;
00104 }
00105 
00106 void ViewProviderPythonFeatureObserver::destruct ()
00107 {
00108     delete _singleton;
00109     _singleton = 0;
00110 }
00111 
00112 void ViewProviderPythonFeatureObserver::slotDeleteDocument(const Gui::Document& d)
00113 {
00114     App::Document* doc = d.getDocument();
00115     std::map<const App::Document*, ObjectProxy>::iterator it = proxyMap.find(doc);
00116     if (it != proxyMap.end()) {
00117         proxyMap.erase(it);
00118     }
00119 }
00120 
00121 void ViewProviderPythonFeatureObserver::slotAppendObject(const Gui::ViewProvider& obj)
00122 {
00123     if (!obj.isDerivedFrom(Gui::ViewProviderDocumentObject::getClassTypeId()))
00124         return;
00125     const Gui::ViewProviderDocumentObject& vp = static_cast<const Gui::ViewProviderDocumentObject&>(obj);
00126     const App::DocumentObject* docobj = vp.getObject();
00127     App::Document* doc = docobj->getDocument();
00128     std::map<const App::Document*, ObjectProxy>::iterator it = proxyMap.find(doc);
00129     if (it != proxyMap.end()) {
00130         ObjectProxy::iterator jt = it->second.find(docobj);
00131         if (jt != it->second.end()) {
00132             Base::PyGILStateLocker lock;
00133             try {
00134                 App::Property* prop = vp.getPropertyByName("Proxy");
00135                 if (prop && prop->isDerivedFrom(App::PropertyPythonObject::getClassTypeId())) {
00136                     static_cast<App::PropertyPythonObject*>(prop)->fromString(jt->second);
00137                     static_cast<App::PropertyPythonObject*>(prop)->touch();
00138                     it->second.erase(jt);
00139                 }
00140             }
00141             catch (Py::Exception& e) {
00142                 e.clear();
00143             }
00144         }
00145         // all cached objects of the documents are already destroyed
00146         else {
00147             it->second.clear();
00148         }
00149     }
00150 }
00151 
00152 void ViewProviderPythonFeatureObserver::slotDeleteObject(const Gui::ViewProvider& obj)
00153 {
00154     if (!obj.isDerivedFrom(Gui::ViewProviderDocumentObject::getClassTypeId()))
00155         return;
00156     const Gui::ViewProviderDocumentObject& vp = static_cast<const Gui::ViewProviderDocumentObject&>(obj);
00157     const App::DocumentObject* docobj = vp.getObject();
00158     App::Document* doc = docobj->getDocument();
00159     if (!doc->getUndoMode())
00160         return; // object will be deleted immediately, thus we don't need to store anything
00161     Base::PyGILStateLocker lock;
00162     try {
00163         App::Property* prop = vp.getPropertyByName("Proxy");
00164         if (prop && prop->isDerivedFrom(App::PropertyPythonObject::getClassTypeId())) {
00165             std::string proxy = static_cast<App::PropertyPythonObject*>(prop)->toString();
00166             proxyMap[doc][docobj] = proxy;
00167         }
00168     }
00169     catch (Py::Exception& e) {
00170         e.clear();
00171     }
00172 }
00173 
00174 ViewProviderPythonFeatureObserver::ViewProviderPythonFeatureObserver()
00175 {
00176     Gui::Application::Instance->signalDeletedObject.connect(boost::bind
00177         (&ViewProviderPythonFeatureObserver::slotDeleteObject, this, _1));
00178     Gui::Application::Instance->signalNewObject.connect(boost::bind
00179         (&ViewProviderPythonFeatureObserver::slotAppendObject, this, _1));
00180     Gui::Application::Instance->signalDeleteDocument.connect(boost::bind
00181         (&ViewProviderPythonFeatureObserver::slotDeleteDocument, this, _1));
00182 }
00183 
00184 ViewProviderPythonFeatureObserver::~ViewProviderPythonFeatureObserver()
00185 {
00186 }
00187 
00188 // ----------------------------------------------------------------------------
00189 
00190 ViewProviderPythonFeatureImp::ViewProviderPythonFeatureImp(ViewProviderDocumentObject* vp)
00191   : object(vp)
00192 {
00193     (void)ViewProviderPythonFeatureObserver::instance();
00194 }
00195 
00196 ViewProviderPythonFeatureImp::~ViewProviderPythonFeatureImp()
00197 {
00198 }
00199 
00200 QIcon ViewProviderPythonFeatureImp::getIcon() const
00201 {
00202     // default icon
00203     //static QPixmap px = BitmapFactory().pixmap("Tree_Python");
00204 
00205     // Run the getIcon method of the proxy object.
00206     Base::PyGILStateLocker lock;
00207     try {
00208         App::Property* proxy = object->getPropertyByName("Proxy");
00209         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00210             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00211             if (vp.hasAttr(std::string("getIcon"))) {
00212                 Py::Callable method(vp.getAttr(std::string("getIcon")));
00213                 Py::Tuple args(0);
00214                 Py::String str(method.apply(args));
00215                 std::string content = str.as_std_string();
00216                 QPixmap icon;
00217                 // Check if the passed string is a filename, otherwise treat as xpm data
00218                 QFileInfo fi(QString::fromAscii(content.c_str()));
00219                 if (fi.isFile() && fi.exists()) {
00220                     icon.load(fi.absoluteFilePath());
00221                 } else {
00222                     QByteArray ary;
00223                     int strlen = (int)content.size();
00224                     ary.resize(strlen);
00225                     for (int j=0; j<strlen; j++)
00226                         ary[j]=content[j];
00227                     // Make sure to remove crap around the XPM data
00228                     QList<QByteArray> lines = ary.split('\n');
00229                     QByteArray buffer;
00230                     buffer.reserve(ary.size()+lines.size());
00231                     for (QList<QByteArray>::iterator it = lines.begin(); it != lines.end(); ++it) {
00232                         QByteArray trim = it->trimmed();
00233                         if (!trim.isEmpty()) {
00234                             buffer.append(trim);
00235                             buffer.append('\n');
00236                         }
00237                     }
00238                     icon.loadFromData(buffer, "XPM");
00239                 }
00240                 if (!icon.isNull()) {
00241                     return icon;
00242                 }
00243             }
00244         }
00245     }
00246     catch (Py::Exception&) {
00247         Base::PyException e; // extract the Python error text
00248         Base::Console().Error("ViewProviderPythonFeature::getIcon: %s\n", e.what());
00249     }
00250 
00251     return QIcon();
00252 }
00253 
00254 std::vector<App::DocumentObject*> ViewProviderPythonFeatureImp::claimChildren() const 
00255 {
00256     std::vector<App::DocumentObject*> children;
00257     Base::PyGILStateLocker lock;
00258     try {
00259         App::Property* proxy = object->getPropertyByName("Proxy");
00260         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00261             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00262             if (vp.hasAttr(std::string("claimChildren"))) {
00263                 Py::Callable method(vp.getAttr(std::string("claimChildren")));
00264                 Py::Tuple args(0);
00265                 Py::Sequence list(method.apply(args));
00266                 for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
00267                     PyObject* item = (*it).ptr();
00268                     if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
00269                         App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
00270                         children.push_back(obj);
00271                     }
00272                 }
00273             }
00274         }
00275     }
00276     catch (Py::Exception&) {
00277         Base::PyException e; // extract the Python error text
00278         Base::Console().Error("ViewProviderPythonFeature::claimChildren: %s\n", e.what());
00279     }
00280 
00281     return children;
00282 }
00283 
00284 std::string ViewProviderPythonFeatureImp::getElement(const SoPickedPoint *pp) const
00285 {
00286     return "";
00287 }
00288 
00289 std::vector<Base::Vector3d> ViewProviderPythonFeatureImp::getSelectionShape(const char* Element) const
00290 {
00291     return std::vector<Base::Vector3d>();
00292 }
00293 
00294 bool ViewProviderPythonFeatureImp::setEdit(int ModNum)
00295 {
00296     // Run the onChanged method of the proxy object.
00297     Base::PyGILStateLocker lock;
00298     try {
00299         App::Property* proxy = object->getPropertyByName("Proxy");
00300         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00301             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00302             if (vp.hasAttr(std::string("setEdit"))) {
00303                 if (vp.hasAttr("__object__")) {
00304                     Py::Callable method(vp.getAttr(std::string("setEdit")));
00305                     Py::Tuple args(1);
00306                     args.setItem(0, Py::Int(ModNum));
00307                     Py::Boolean ok(method.apply(args));
00308                     return (bool)ok;
00309                 }
00310                 else {
00311                     Py::Callable method(vp.getAttr(std::string("setEdit")));
00312                     Py::Tuple args(2);
00313                     args.setItem(0, Py::Object(object->getPyObject(), true));
00314                     args.setItem(1, Py::Int(ModNum));
00315                     Py::Boolean ok(method.apply(args));
00316                     return (bool)ok;
00317                 }
00318             }
00319         }
00320     }
00321     catch (Py::Exception&) {
00322         Base::PyException e; // extract the Python error text
00323         const char* name = object->getObject()->Label.getValue();
00324         Base::Console().Error("ViewProviderPythonFeature::setEdit (%s): %s\n", name, e.what());
00325     }
00326 
00327     return false;
00328 }
00329 
00330 bool ViewProviderPythonFeatureImp::unsetEdit(int ModNum)
00331 {
00332     // Run the onChanged method of the proxy object.
00333     Base::PyGILStateLocker lock;
00334     try {
00335         App::Property* proxy = object->getPropertyByName("Proxy");
00336         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00337             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00338             if (vp.hasAttr(std::string("unsetEdit"))) {
00339                 if (vp.hasAttr("__object__")) {
00340                     Py::Callable method(vp.getAttr(std::string("unsetEdit")));
00341                     Py::Tuple args(1);
00342                     args.setItem(0, Py::Int(ModNum));
00343                     Py::Boolean ok(method.apply(args));
00344                     return (bool)ok;
00345                 }
00346                 else {
00347                     Py::Callable method(vp.getAttr(std::string("unsetEdit")));
00348                     Py::Tuple args(2);
00349                     args.setItem(0, Py::Object(object->getPyObject(), true));
00350                     args.setItem(1, Py::Int(ModNum));
00351                     Py::Boolean ok(method.apply(args));
00352                     return (bool)ok;
00353                 }
00354             }
00355         }
00356     }
00357     catch (Py::Exception&) {
00358         Base::PyException e; // extract the Python error text
00359         const char* name = object->getObject()->Label.getValue();
00360         Base::Console().Error("ViewProviderPythonFeature::unsetEdit (%s): %s\n", name, e.what());
00361     }
00362 
00363     return false;
00364 }
00365 
00366 void ViewProviderPythonFeatureImp::attach(App::DocumentObject *pcObject)
00367 {
00368     // Run the attach method of the proxy object.
00369     Base::PyGILStateLocker lock;
00370     try {
00371         App::Property* proxy = object->getPropertyByName("Proxy");
00372         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00373             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00374             if (vp.hasAttr(std::string("attach"))) {
00375                 if (vp.hasAttr("__object__")) {
00376                     Py::Callable method(vp.getAttr(std::string("attach")));
00377                     Py::Tuple args(0);
00378                     method.apply(args);
00379                 }
00380                 else {
00381                     Py::Callable method(vp.getAttr(std::string("attach")));
00382                     Py::Tuple args(1);
00383                     args.setItem(0, Py::Object(object->getPyObject(), true));
00384                     method.apply(args);
00385                 }
00386             }
00387         }
00388     }
00389     catch (Py::Exception&) {
00390         Base::PyException e; // extract the Python error text
00391         const char* name = object->getObject()->Label.getValue();
00392         Base::Console().Error("ViewProviderPythonFeature::attach (%s): %s\n", name, e.what());
00393     }
00394 }
00395 
00396 void ViewProviderPythonFeatureImp::updateData(const App::Property* prop)
00397 {
00398     // Run the updateData method of the proxy object.
00399     Base::PyGILStateLocker lock;
00400     try {
00401         App::Property* proxy = object->getPropertyByName("Proxy");
00402         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00403             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00404             if (vp.hasAttr(std::string("updateData"))) {
00405                 if (vp.hasAttr("__object__")) {
00406                     Py::Callable method(vp.getAttr(std::string("updateData")));
00407                     Py::Tuple args(1);
00408                     const char* prop_name = object->getObject()->getName(prop);
00409                     if (prop_name) {
00410                         args.setItem(0, Py::String(prop_name));
00411                         method.apply(args);
00412                     }
00413                 }
00414                 else {
00415                     Py::Callable method(vp.getAttr(std::string("updateData")));
00416                     Py::Tuple args(2);
00417                     args.setItem(0, Py::Object(object->getObject()->getPyObject(), true));
00418                     const char* prop_name = object->getObject()->getName(prop);
00419                     if (prop_name) {
00420                         args.setItem(1, Py::String(prop_name));
00421                         method.apply(args);
00422                     }
00423                 }
00424             }
00425         }
00426     }
00427     catch (Py::Exception&) {
00428         Base::PyException e; // extract the Python error text
00429         const char* name = object->getObject()->Label.getValue();
00430         Base::Console().Error("ViewProviderPythonFeature::updateData (%s): %s\n", name, e.what());
00431     }
00432 }
00433 
00434 void ViewProviderPythonFeatureImp::onChanged(const App::Property* prop)
00435 {
00436     // Run the onChanged method of the proxy object.
00437     Base::PyGILStateLocker lock;
00438     try {
00439         App::Property* proxy = object->getPropertyByName("Proxy");
00440         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00441             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00442             if (vp.hasAttr(std::string("onChanged"))) {
00443                 if (vp.hasAttr("__object__")) {
00444                     Py::Callable method(vp.getAttr(std::string("onChanged")));
00445                     Py::Tuple args(1);
00446                     std::string prop_name = object->getName(prop);
00447                     args.setItem(0, Py::String(prop_name));
00448                     method.apply(args);
00449                 }
00450                 else {
00451                     Py::Callable method(vp.getAttr(std::string("onChanged")));
00452                     Py::Tuple args(2);
00453                     args.setItem(0, Py::Object(object->getPyObject(), true));
00454                     std::string prop_name = object->getName(prop);
00455                     args.setItem(1, Py::String(prop_name));
00456                     method.apply(args);
00457                 }
00458             }
00459         }
00460     }
00461     catch (Py::Exception&) {
00462         Base::PyException e; // extract the Python error text
00463         const char* name = object->getObject()->Label.getValue();
00464         Base::Console().Error("ViewProviderPythonFeature::onChanged (%s): %s\n", name, e.what());
00465     }
00466 }
00467 
00468 void ViewProviderPythonFeatureImp::startRestoring()
00469 {
00470 }
00471 
00472 void ViewProviderPythonFeatureImp::finishRestoring()
00473 {
00474     App::Property* proxy = object->getPropertyByName("Proxy");
00475     if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00476         Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00477         if (vp.ptr() == Py::_None()) {
00478             object->show();
00479             static_cast<App::PropertyPythonObject*>(proxy)->setValue(Py::Int(1));
00480         }
00481     }
00482 }
00483 
00484 const char* ViewProviderPythonFeatureImp::getDefaultDisplayMode() const
00485 {
00486     // Run the getDefaultDisplayMode method of the proxy object.
00487     Base::PyGILStateLocker lock;
00488     static std::string mode;
00489     try {
00490         App::Property* proxy = object->getPropertyByName("Proxy");
00491         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00492             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00493             if (vp.hasAttr(std::string("getDefaultDisplayMode"))) {
00494                 Py::Callable method(vp.getAttr(std::string("getDefaultDisplayMode")));
00495                 Py::Tuple args(0);
00496                 Py::String str(method.apply(args));
00497                 mode = str.as_std_string();
00498                 return mode.c_str();
00499             }
00500         }
00501     }
00502     catch (Py::Exception&) {
00503         Base::PyException e; // extract the Python error text
00504         const char* name = object->getObject()->Label.getValue();
00505         Base::Console().Error("ViewProviderPythonFeature::getDefaultDisplayMode (%s): %s\n", name, e.what());
00506     }
00507 
00508     return 0;
00509 }
00510 
00511 std::vector<std::string> ViewProviderPythonFeatureImp::getDisplayModes(void) const
00512 {
00513     // Run the getDisplayModes method of the proxy object.
00514     Base::PyGILStateLocker lock;
00515     std::vector<std::string> modes;
00516     try {
00517         App::Property* proxy = object->getPropertyByName("Proxy");
00518         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00519             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00520             if (vp.hasAttr(std::string("getDisplayModes"))) {
00521                 if (vp.hasAttr("__object__")) {
00522                     Py::Callable method(vp.getAttr(std::string("getDisplayModes")));
00523                     Py::Tuple args(0);
00524                     Py::List list(method.apply(args));
00525                     for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00526                         Py::String str(*it);
00527                         modes.push_back(str.as_std_string());
00528                     }
00529                 }
00530                 else {
00531                     Py::Callable method(vp.getAttr(std::string("getDisplayModes")));
00532                     Py::Tuple args(1);
00533                     args.setItem(0, Py::Object(object->getPyObject(), true));
00534                     Py::List list(method.apply(args));
00535                     for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00536                         Py::String str(*it);
00537                         modes.push_back(str.as_std_string());
00538                     }
00539                 }
00540             }
00541         }
00542     }
00543     catch (Py::Exception&) {
00544         Base::PyException e; // extract the Python error text
00545         const char* name = object->getObject()->Label.getValue();
00546         Base::Console().Error("ViewProviderPythonFeature::getDisplayModes (%s): %s\n", name, e.what());
00547     }
00548 
00549     return modes;
00550 }
00551 
00552 std::string ViewProviderPythonFeatureImp::setDisplayMode(const char* ModeName)
00553 {
00554     // Run the setDisplayMode method of the proxy object.
00555     Base::PyGILStateLocker lock;
00556     try {
00557         App::Property* proxy = object->getPropertyByName("Proxy");
00558         if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
00559             Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
00560             if (vp.hasAttr(std::string("setDisplayMode"))) {
00561                 Py::Callable method(vp.getAttr(std::string("setDisplayMode")));
00562                 Py::Tuple args(1);
00563                 args.setItem(0, Py::String(ModeName));
00564                 Py::String str(method.apply(args));
00565                 return str.as_std_string();
00566             }
00567         }
00568     }
00569     catch (Py::Exception&) {
00570         Base::PyException e; // extract the Python error text
00571         const char* name = object->getObject()->Label.getValue();
00572         Base::Console().Error("ViewProviderPythonFeature::setDisplayMode (%s): %s\n", name, e.what());
00573     }
00574 
00575     return ModeName;
00576 }
00577 
00578 // ---------------------------------------------------------
00579 
00580 namespace Gui {
00581 PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderPythonFeature, Gui::ViewProviderDocumentObject)
00582 // explicit template instantiation
00583 template class GuiExport ViewProviderPythonFeatureT<ViewProviderDocumentObject>;
00584 }
00585 
00586 // ---------------------------------------------------------
00587 
00588 namespace Gui {
00589 PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderPythonGeometry, Gui::ViewProviderGeometryObject)
00590 // explicit template instantiation
00591 template class GuiExport ViewProviderPythonFeatureT<ViewProviderGeometryObject>;
00592 }
00593 
00594 

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