00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <sstream>
00028 #endif
00029
00030 #include "Document.h"
00031 #include <Base/FileInfo.h>
00032 #include <Base/PyTools.h>
00033 #include "DocumentObject.h"
00034 #include "DocumentObjectPy.h"
00035
00036
00037 #include "DocumentPy.h"
00038 #include "DocumentPy.cpp"
00039 #include <boost/regex.hpp>
00040
00041 using namespace App;
00042
00043
00044
00045 std::string DocumentPy::representation(void) const
00046 {
00047 std::stringstream str;
00048 str << "<Document object at " << getDocumentPtr() << ">";
00049
00050 return str.str();
00051 }
00052
00053 PyObject* DocumentPy::save(PyObject * args)
00054 {
00055 if (!PyArg_ParseTuple(args, ""))
00056 return NULL;
00057 if (!getDocumentPtr()->save()) {
00058 PyErr_Format(PyExc_ValueError, "Object attribute 'FileName' is not set");
00059 return NULL;
00060 }
00061
00062 const char* filename = getDocumentPtr()->FileName.getValue();
00063 Base::FileInfo fi(filename);
00064 if (!fi.isReadable()) {
00065 PyErr_Format(PyExc_IOError, "No such file or directory: '%s'", filename);
00066 return NULL;
00067 }
00068
00069 Py_Return;
00070 }
00071
00072 PyObject* DocumentPy::restore(PyObject * args)
00073 {
00074 if (!PyArg_ParseTuple(args, ""))
00075 return NULL;
00076 const char* filename = getDocumentPtr()->FileName.getValue();
00077 if (!filename || *filename == '\0') {
00078 PyErr_Format(PyExc_ValueError, "Object attribute 'FileName' is not set");
00079 return NULL;
00080 }
00081 Base::FileInfo fi(filename);
00082 if (!fi.isReadable()) {
00083 PyErr_Format(PyExc_IOError, "No such file or directory: '%s'", filename);
00084 return NULL;
00085 }
00086 try {
00087 getDocumentPtr()->restore();
00088 } catch (...) {
00089 PyErr_Format(PyExc_IOError, "Reading from file '%s' failed", filename);
00090 return NULL;
00091 }
00092 Py_Return;
00093 }
00094
00095 PyObject* DocumentPy::addObject(PyObject *args)
00096 {
00097 char *sType,*sName=0;
00098 PyObject* obj=0;
00099 PyObject* view=0;
00100 if (!PyArg_ParseTuple(args, "s|sOO", &sType,&sName,&obj,&view))
00101 return NULL;
00102
00103 DocumentObject *pcFtr;
00104
00105 pcFtr = getDocumentPtr()->addObject(sType,sName);
00106 if (pcFtr) {
00107
00108 if (obj) {
00109 try {
00110
00111 Py::Object pyftr = Py::asObject(pcFtr->getPyObject());
00112
00113 Py::Object pyobj(obj);
00114 if (pyobj.hasAttr("__object__")) {
00115 pyobj.setAttr("__object__", pyftr);
00116 }
00117 pyftr.setAttr("Proxy", pyobj);
00118
00119
00120
00121 Py::Object pyvp;
00122 if (view)
00123 pyvp = Py::Object(view);
00124 if (pyvp.isNone())
00125 pyvp = Py::Int(1);
00126
00127 if (pyvp.hasAttr("__vobject__")) {
00128 pyvp.setAttr("__vobject__", pyftr.getAttr("ViewObject"));
00129 }
00130 pyftr.getAttr("ViewObject").setAttr("Proxy", pyvp);
00131 return Py::new_reference_to(Py::None());
00132 }
00133 catch (Py::Exception& e) {
00134 e.clear();
00135 }
00136 }
00137 return pcFtr->getPyObject();
00138 }
00139 else {
00140 std::stringstream str;
00141 str << "No document object found of type '" << sType << "'" << std::ends;
00142 throw Py::Exception(PyExc_Exception,str.str());
00143 }
00144 }
00145
00146 PyObject* DocumentPy::removeObject(PyObject *args)
00147 {
00148 char *sName;
00149 if (!PyArg_ParseTuple(args, "s",&sName))
00150 return NULL;
00151
00152
00153 DocumentObject *pcFtr = getDocumentPtr()->getObject(sName);
00154 if(pcFtr) {
00155 getDocumentPtr()->remObject( sName );
00156 Py_Return;
00157 } else {
00158 std::stringstream str;
00159 str << "No document object found with name '" << sName << "'" << std::ends;
00160 throw Py::Exception(PyExc_Exception,str.str());
00161 }
00162 }
00163
00164 PyObject* DocumentPy::copyObject(PyObject *args)
00165 {
00166 PyObject *obj, *rec=0;
00167 if (!PyArg_ParseTuple(args, "O!|O!",&(DocumentObjectPy::Type),&obj,&PyBool_Type,&rec))
00168 return NULL;
00169
00170 DocumentObjectPy* docObj = static_cast<DocumentObjectPy*>(obj);
00171 DocumentObject* copy = getDocumentPtr()->copyObject(docObj->getDocumentObjectPtr(), rec==Py_True);
00172 if (copy) {
00173 return copy->getPyObject();
00174 }
00175 else {
00176 std::string str("Failed to copy the object");
00177 throw Py::Exception(PyExc_Exception,str);
00178 }
00179 }
00180
00181 PyObject* DocumentPy::moveObject(PyObject *args)
00182 {
00183 PyObject *obj, *rec=0;
00184 if (!PyArg_ParseTuple(args, "O!|O!",&(DocumentObjectPy::Type),&obj,&PyBool_Type,&rec))
00185 return NULL;
00186
00187 DocumentObjectPy* docObj = static_cast<DocumentObjectPy*>(obj);
00188 DocumentObject* move = getDocumentPtr()->moveObject(docObj->getDocumentObjectPtr(), rec==Py_True);
00189 if (move) {
00190 return move->getPyObject();
00191 }
00192 else {
00193 std::string str("Failed to move the object");
00194 throw Py::Exception(PyExc_Exception,str);
00195 }
00196 }
00197
00198 PyObject* DocumentPy::openTransaction(PyObject *args)
00199 {
00200 char *pstr=0;
00201 if (!PyArg_ParseTuple(args, "|s", &pstr))
00202 return NULL;
00203
00204 getDocumentPtr()->openTransaction(pstr);
00205 Py_Return;
00206 }
00207
00208 PyObject* DocumentPy::abortTransaction(PyObject * args)
00209 {
00210 if (!PyArg_ParseTuple(args, ""))
00211 return NULL;
00212 getDocumentPtr()->abortTransaction();
00213 Py_Return;
00214 }
00215
00216 PyObject* DocumentPy::commitTransaction(PyObject * args)
00217 {
00218 if (!PyArg_ParseTuple(args, ""))
00219 return NULL;
00220 getDocumentPtr()->commitTransaction();
00221 Py_Return;
00222 }
00223
00224 PyObject* DocumentPy::undo(PyObject * args)
00225 {
00226 if (!PyArg_ParseTuple(args, ""))
00227 return NULL;
00228 if (getDocumentPtr()->getAvailableUndos())
00229 getDocumentPtr()->undo();
00230 Py_Return;
00231 }
00232
00233 PyObject* DocumentPy::redo(PyObject * args)
00234 {
00235 if (!PyArg_ParseTuple(args, ""))
00236 return NULL;
00237 if (getDocumentPtr()->getAvailableRedos())
00238 getDocumentPtr()->redo();
00239 Py_Return;
00240 }
00241
00242 PyObject* DocumentPy::clearUndos(PyObject * args)
00243 {
00244 if (!PyArg_ParseTuple(args, ""))
00245 return NULL;
00246 getDocumentPtr()->clearUndos();
00247 Py_Return;
00248 }
00249
00250 PyObject* DocumentPy::recompute(PyObject * args)
00251 {
00252 if (!PyArg_ParseTuple(args, ""))
00253 return NULL;
00254 getDocumentPtr()->recompute();
00255 Py_Return;
00256 }
00257
00258 PyObject* DocumentPy::getObject(PyObject *args)
00259 {
00260 char *sName;
00261 if (!PyArg_ParseTuple(args, "s",&sName))
00262 return NULL;
00263
00264 DocumentObject *pcFtr = getDocumentPtr()->getObject(sName);
00265 if (pcFtr)
00266 return pcFtr->getPyObject();
00267 else
00268 Py_Return;
00269 }
00270
00271 PyObject* DocumentPy::getObjectsByLabel(PyObject *args)
00272 {
00273 char *sName;
00274 if (!PyArg_ParseTuple(args, "s",&sName))
00275 return NULL;
00276
00277 Py::List list;
00278 std::string name = sName;
00279 std::vector<DocumentObject*> objs = getDocumentPtr()->getObjects();
00280 for (std::vector<DocumentObject*>::iterator it = objs.begin(); it != objs.end(); ++it) {
00281 if (name == (*it)->Label.getValue())
00282 list.append(Py::asObject((*it)->getPyObject()));
00283 }
00284
00285 return Py::new_reference_to(list);
00286 }
00287
00288 PyObject* DocumentPy::findObjects(PyObject *args)
00289 {
00290 char *sType="App::DocumentObject", *sName=0;
00291 if (!PyArg_ParseTuple(args, "|ss",&sType, &sName))
00292 return NULL;
00293
00294 Base::Type type = Base::Type::fromName(sType);
00295 if (type == Base::Type::badType()) {
00296 PyErr_Format(PyExc_Exception, "'%s' is not a valid type", sType);
00297 return NULL;
00298 }
00299
00300 if (!type.isDerivedFrom(App::DocumentObject::getClassTypeId())) {
00301 PyErr_Format(PyExc_Exception, "Type '%s' does not inherit from 'App::DocumentObject'", sType);
00302 return NULL;
00303 }
00304
00305 std::vector<DocumentObject*> res;
00306 std::vector<DocumentObject*> objs = getDocumentPtr()->getObjectsOfType(type);
00307
00308 if (sName) {
00309 try {
00310 boost::regex rx(sName);
00311 boost::cmatch what;
00312 for (std::vector<DocumentObject*>::const_iterator It = objs.begin();It != objs.end();++It) {
00313 if (boost::regex_match((*It)->getNameInDocument(), what, rx))
00314 res.push_back(*It);
00315 }
00316 }
00317 catch (const boost::regex_error& e) {
00318 PyErr_SetString(PyExc_RuntimeError, e.what());
00319 return 0;
00320 }
00321 }
00322 else {
00323 res = objs;
00324 }
00325
00326 Py_ssize_t index=0;
00327 PyObject* list = PyList_New((Py_ssize_t)res.size());
00328 for (std::vector<DocumentObject*>::const_iterator It = res.begin();It != res.end();++It, index++)
00329 PyList_SetItem(list, index, (*It)->getPyObject());
00330 return list;
00331 }
00332
00333 Py::Object DocumentPy::getActiveObject(void) const
00334 {
00335 DocumentObject *pcFtr = getDocumentPtr()->getActiveObject();
00336 if(pcFtr)
00337 return Py::Object(pcFtr->getPyObject(), true);
00338 return Py::None();
00339 }
00340
00341 PyObject* DocumentPy::supportedTypes(PyObject *args)
00342 {
00343 if (!PyArg_ParseTuple(args, ""))
00344 return NULL;
00345
00346 std::vector<Base::Type> ary;
00347 Base::Type::getAllDerivedFrom(App::DocumentObject::getClassTypeId(), ary);
00348 Py::List res;
00349 for (std::vector<Base::Type>::iterator it = ary.begin(); it != ary.end(); ++it)
00350 res.append(Py::String(it->getName()));
00351 return Py::new_reference_to(res);
00352 }
00353
00354 Py::List DocumentPy::getObjects(void) const
00355 {
00356 std::vector<DocumentObject*> objs = getDocumentPtr()->getObjects();
00357 Py::List res;
00358
00359 for (std::vector<DocumentObject*>::const_iterator It = objs.begin();It != objs.end();++It)
00360
00361 res.append(Py::Object((*It)->getPyObject(), true));
00362
00363 return res;
00364 }
00365
00366 Py::Int DocumentPy::getUndoMode(void) const
00367 {
00368 return Py::Int(getDocumentPtr()->getUndoMode());
00369 }
00370
00371 void DocumentPy::setUndoMode(Py::Int arg)
00372 {
00373 getDocumentPtr()->setUndoMode(arg);
00374 }
00375
00376 Py::Int DocumentPy::getUndoRedoMemSize(void) const
00377 {
00378 return Py::Int((long)getDocumentPtr()->getUndoMemSize());
00379 }
00380
00381 Py::Int DocumentPy::getUndoCount(void) const
00382 {
00383 return Py::Int((long)getDocumentPtr()->getAvailableUndos());
00384 }
00385
00386 Py::Int DocumentPy::getRedoCount(void) const
00387 {
00388 return Py::Int((long)getDocumentPtr()->getAvailableRedos());
00389 }
00390
00391 Py::List DocumentPy::getUndoNames(void) const
00392 {
00393 std::vector<std::string> vList = getDocumentPtr()->getAvailableUndoNames();
00394 Py::List res;
00395
00396 for (std::vector<std::string>::const_iterator It = vList.begin();It!=vList.end();++It)
00397 res.append(Py::String(*It));
00398
00399 return res;
00400 }
00401
00402 Py::List DocumentPy::getRedoNames(void) const
00403 {
00404 std::vector<std::string> vList = getDocumentPtr()->getAvailableRedoNames();
00405 Py::List res;
00406
00407 for (std::vector<std::string>::const_iterator It = vList.begin();It!=vList.end();++It)
00408 res.append(Py::String(*It));
00409
00410 return res;
00411 }
00412
00413 Py::String DocumentPy::getDependencyGraph(void) const
00414 {
00415 std::stringstream out;
00416 getDocumentPtr()->writeDependencyGraphViz(out);
00417 return Py::String(out.str());
00418 }
00419
00420 Py::String DocumentPy::getName(void) const
00421 {
00422 return Py::String(getDocumentPtr()->getName());
00423 }
00424
00425 PyObject* DocumentPy::getTempFileName(PyObject *args)
00426 {
00427 PyObject *value;
00428 if (!PyArg_ParseTuple(args, "O",&value))
00429 return NULL;
00430
00431 std::string string;
00432 if (PyUnicode_Check(value)) {
00433 PyObject* unicode = PyUnicode_AsUTF8String(value);
00434 string = PyString_AsString(unicode);
00435 Py_DECREF(unicode);
00436 }
00437 else if (PyString_Check(value)) {
00438 string = PyString_AsString(value);
00439 }
00440 else {
00441 std::string error = std::string("type must be a string!");
00442 error += value->ob_type->tp_name;
00443 throw Py::TypeError(error);
00444 }
00445
00446
00447 Base::FileInfo fileName(Base::FileInfo::getTempFileName
00448 (string.c_str(),getDocumentPtr()->TransientDir.getValue()));
00449
00450 fileName.deleteFile();
00451
00452 PyObject *p = PyUnicode_DecodeUTF8(fileName.filePath().c_str(),fileName.filePath().size(),0);
00453 if (!p) throw Base::Exception("UTF8 conversion failure at PropertyString::getPyObject()");
00454 return p;
00455 }
00456
00457 PyObject *DocumentPy::getCustomAttributes(const char* attr) const
00458 {
00459
00460
00461
00462
00463
00464 App::Property* prop = getPropertyContainerPtr()->getPropertyByName(attr);
00465 if (prop) return 0;
00466 if (this->ob_type->tp_dict == NULL) {
00467 if (PyType_Ready(this->ob_type) < 0)
00468 return 0;
00469 }
00470 PyObject* item = PyDict_GetItemString(this->ob_type->tp_dict, attr);
00471 if (item) return 0;
00472
00473 DocumentObject* obj = getDocumentPtr()->getObject(attr);
00474 return (obj ? obj->getPyObject() : 0);
00475 }
00476
00477 int DocumentPy::setCustomAttributes(const char* attr, PyObject *)
00478 {
00479
00480
00481
00482
00483
00484 App::Property* prop = getPropertyContainerPtr()->getPropertyByName(attr);
00485 if (prop) return 0;
00486 if (this->ob_type->tp_dict == NULL) {
00487 if (PyType_Ready(this->ob_type) < 0)
00488 return 0;
00489 }
00490 PyObject* item = PyDict_GetItemString(this->ob_type->tp_dict, attr);
00491 if (item) return 0;
00492 DocumentObject* obj = getDocumentPtr()->getObject(attr);
00493 if (obj)
00494 {
00495 std::stringstream str;
00496 str << "'Document' object attribute '" << attr
00497 << "' must not be set this way" << std::ends;
00498 throw Py::AttributeError(str.str());
00499 }
00500
00501 return 0;
00502 }