00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "PreCompiled.h"
00028
00029 #ifndef _PreComp_
00030 # include <stdexcept>
00031 #endif
00032
00033
00034 #include "Application.h"
00035 #include "Document.h"
00036 #include "DocumentPy.h"
00037 #include "DocumentObserverPython.h"
00038
00039
00040 #include <Base/Interpreter.h>
00041 #include <Base/Exception.h>
00042 #include <Base/Parameter.h>
00043 #include <Base/Console.h>
00044 #include <Base/Factory.h>
00045 #include <Base/FileInfo.h>
00046 #include <Base/UnitsApi.h>
00047
00048 #define new DEBUG_CLIENTBLOCK
00049
00050 using namespace Base;
00051 using namespace App;
00052
00053
00054
00055
00056
00057
00058
00059 PyMethodDef Application::Methods[] = {
00060 {"ParamGet", (PyCFunction) Application::sGetParam, 1,
00061 "Get parameters by path"},
00062 {"Version", (PyCFunction) Application::sGetVersion, 1,
00063 "Print the version to the output."},
00064 {"ConfigGet", (PyCFunction) Application::sGetConfig, 1,
00065 "ConfigGet([string]) -- Get the value for the given key.\n"
00066 "If no key is given the complete configuration is dumped to\n"
00067 "the output."},
00068 {"ConfigSet", (PyCFunction) Application::sSetConfig, 1,
00069 "ConfigSet(string, string) -- Set the given key to the given value."},
00070 {"ConfigDump", (PyCFunction) Application::sDumpConfig, 1,
00071 "Dump the configuration to the output."},
00072 {"addImportType", (PyCFunction) Application::sAddImportType, 1,
00073 "Register filetype for import"},
00074 {"getImportType", (PyCFunction) Application::sGetImportType, 1,
00075 "Get the name of the module that can import the filetype"},
00076 {"EndingAdd", (PyCFunction) Application::sAddImportType ,1,
00077 "deprecated -- use addImportType"},
00078 {"EndingGet", (PyCFunction) Application::sGetImportType ,1,
00079 "deprecated -- use getImportType"},
00080 {"addExportType", (PyCFunction) Application::sAddExportType ,1,
00081 "Register filetype for export"},
00082 {"getExportType", (PyCFunction) Application::sGetExportType ,1,
00083 "Get the name of the module that can export the filetype"},
00084 {"getResourceDir", (PyCFunction) Application::sGetResourceDir ,1,
00085 "Get the root directory of all resources"},
00086 {"getHomePath", (PyCFunction) Application::sGetHomePath ,1,
00087 "Get the home path, i.e. the parent directory of the executable"},
00088
00089 {"loadFile", (PyCFunction) Application::sLoadFile, 1,
00090 "loadFile(string=filename,[string=module]) -> None\n\n"
00091 "Loads an arbitrary file by delegating to the given Python module:\n"
00092 "* If no module is given it will be determined by the file extension.\n"
00093 "* If more than one module can load a file the first one one will be taken.\n"
00094 "* If no module exists to load the file an exception will be raised."},
00095 {"open", (PyCFunction) Application::sOpenDocument, 1,
00096 "See openDocument(string)"},
00097 {"openDocument", (PyCFunction) Application::sOpenDocument, 1,
00098 "openDocument(string) -> object\n\n"
00099 "Create a document and load the project file into the document.\n"
00100 "The string argument must point to an existing file. If the file doesn't exist\n"
00101 "or the file cannot be loaded an I/O exception is thrown. In this case the\n"
00102 "document is kept alive."},
00103
00104
00105
00106 {"newDocument", (PyCFunction) Application::sNewDocument, 1,
00107 "newDocument([string]) -> object\n\n"
00108 "Create a new document with a given name.\n"
00109 "The document name must be unique which\n"
00110 "is checked automatically."},
00111 {"closeDocument", (PyCFunction) Application::sCloseDocument, 1,
00112 "closeDocument(string) -> None\n\n"
00113 "Close the document with a given name."},
00114 {"activeDocument", (PyCFunction) Application::sActiveDocument, 1,
00115 "activeDocument() -> object or None\n\n"
00116 "Return the active document or None if there is no one."},
00117 {"setActiveDocument",(PyCFunction) Application::sSetActiveDocument, 1,
00118 "setActiveDocement(string) -> None\n\n"
00119 "Set the active document by its name."},
00120 {"getDocument", (PyCFunction) Application::sGetDocument, 1,
00121 "getDocument(string) -> object\n\n"
00122 "Get a document by its name or raise an exception\n"
00123 "if there is no document with the given name."},
00124 {"listDocuments", (PyCFunction) Application::sListDocuments ,1,
00125 "listDocuments() -> list\n\n"
00126 "Return a list of names of all documents."},
00127 {"addDocumentObserver", (PyCFunction) Application::sAddDocObserver ,1,
00128 "addDocumentObserver() -> None\n\n"
00129 "Add an observer to get notified about changes on documents."},
00130 {"removeDocumentObserver", (PyCFunction) Application::sRemoveDocObserver ,1,
00131 "removeDocumentObserver() -> None\n\n"
00132 "Remove an added document observer."},
00133
00134 {NULL, NULL, 0, NULL}
00135 };
00136
00137
00138 PyObject* Application::sLoadFile(PyObject * , PyObject *args,PyObject * )
00139 {
00140 char *path, *doc="",*mod="";
00141 if (!PyArg_ParseTuple(args, "s|ss", &path, &doc, &mod))
00142 return 0;
00143 try {
00144 Base::FileInfo fi(path);
00145 if (!fi.isFile() || !fi.exists()) {
00146 PyErr_Format(PyExc_IOError, "File %s doesn't exist.", path);
00147 return 0;
00148 }
00149
00150 std::string module = mod;
00151 if (module.empty()) {
00152 std::string ext = fi.extension(false);
00153 std::vector<std::string> modules = GetApplication().getImportModules(ext.c_str());
00154 if (modules.empty()) {
00155 PyErr_Format(PyExc_IOError, "Filetype %s is not supported.", ext.c_str());
00156 return 0;
00157 }
00158 else {
00159 module = modules.front();
00160 }
00161 }
00162
00163 std::stringstream str;
00164 str << "import " << module << std::endl;
00165 if (fi.hasExtension("FCStd"))
00166 str << module << ".openDocument('" << path << "')" << std::endl;
00167 else
00168 str << module << ".insert('" << path << "','" << doc << "')" << std::endl;
00169 Base::Interpreter().runString(str.str().c_str());
00170 Py_Return;
00171 }
00172 catch (const Base::Exception& e) {
00173 PyErr_SetString(PyExc_IOError, e.what());
00174 return 0;
00175 }
00176 catch (const std::exception& e) {
00177
00178 PyErr_Format(PyExc_IOError, "Invalid project file %s: %s", path, e.what());
00179 return 0;
00180 }
00181 }
00182
00183 PyObject* Application::sOpenDocument(PyObject * , PyObject *args,PyObject * )
00184 {
00185 char *pstr;
00186 if (!PyArg_ParseTuple(args, "s", &pstr))
00187 return NULL;
00188 try {
00189
00190 return (GetApplication().openDocument(pstr)->getPyObject());
00191 }
00192 catch (const Base::Exception& e) {
00193 PyErr_SetString(PyExc_IOError, e.what());
00194 return 0L;
00195 }
00196 catch (const std::exception& e) {
00197
00198 PyErr_Format(PyExc_IOError, "Invalid project file %s: %s\n", pstr, e.what());
00199 return 0L;
00200 }
00201 }
00202
00203 PyObject* Application::sNewDocument(PyObject * , PyObject *args,PyObject * )
00204 {
00205 char *docName = 0;
00206 char *usrName = 0;
00207 if (!PyArg_ParseTuple(args, "|ss", &docName, &usrName))
00208 return NULL;
00209
00210 PY_TRY {
00211 return GetApplication().newDocument(docName, usrName)->getPyObject();
00212 }PY_CATCH;
00213 }
00214
00215 PyObject* Application::sSetActiveDocument(PyObject * , PyObject *args,PyObject * )
00216 {
00217 char *pstr = 0;
00218 if (!PyArg_ParseTuple(args, "s", &pstr))
00219 return NULL;
00220
00221 try {
00222 GetApplication().setActiveDocument(pstr);
00223 }
00224 catch (const Base::Exception& e) {
00225 PyErr_SetString(PyExc_Exception, e.what());
00226 return NULL;
00227 }
00228
00229 Py_Return;
00230 }
00231
00232 PyObject* Application::sCloseDocument(PyObject * , PyObject *args,PyObject * )
00233 {
00234 char *pstr = 0;
00235 if (!PyArg_ParseTuple(args, "s", &pstr))
00236 return NULL;
00237
00238 Document* doc = GetApplication().getDocument(pstr);
00239 if (!doc) {
00240 PyErr_Format(PyExc_NameError, "Unknown document '%s'", pstr);
00241 return NULL;
00242 }
00243 if (!doc->isClosable()) {
00244 PyErr_Format(PyExc_RuntimeError, "The document '%s' is not closable for the moment", pstr);
00245 return NULL;
00246 }
00247
00248 if (GetApplication().closeDocument(pstr) == false) {
00249 PyErr_Format(PyExc_RuntimeError, "Closing the document '%s' failed", pstr);
00250 return NULL;
00251 }
00252
00253 Py_Return;
00254 }
00255
00256 PyObject* Application::sSaveDocument(PyObject * , PyObject *args,PyObject * )
00257 {
00258 char *pDoc;
00259 if (!PyArg_ParseTuple(args, "s", &pDoc))
00260 return NULL;
00261
00262 Document* doc = GetApplication().getDocument(pDoc);
00263 if ( doc ) {
00264 if ( doc->save() == false ) {
00265 PyErr_Format(PyExc_Exception, "Cannot save document '%s'", pDoc);
00266 return 0L;
00267 }
00268 }
00269 else {
00270 PyErr_Format(PyExc_NameError, "Unknown document '%s'", pDoc);
00271 return NULL;
00272 }
00273
00274 Py_Return;
00275 }
00276 #if 0
00277 PyObject* Application::sSaveDocumentAs(PyObject * , PyObject *args,PyObject * )
00278 {
00279 char *pDoc, *pFileName;
00280 if (!PyArg_ParseTuple(args, "ss", &pDoc, &pFileName))
00281 return NULL;
00282
00283 Document* doc = GetApplication().getDocument(pDoc);
00284 if (doc) {
00285 doc->saveAs( pFileName );
00286 }
00287 else {
00288 PyErr_Format(PyExc_NameError, "Unknown document '%s'", pDoc);
00289 return NULL;
00290 }
00291
00292 Py_Return;
00293 }
00294 #endif
00295 PyObject* Application::sActiveDocument(PyObject * , PyObject *args,PyObject * )
00296 {
00297 if (!PyArg_ParseTuple(args, ""))
00298 return NULL;
00299
00300 Document* doc = GetApplication().getActiveDocument();
00301 if (doc) {
00302 return doc->getPyObject();
00303 }
00304 else {
00305 Py_INCREF(Py_None);
00306 return Py_None;
00307 }
00308 }
00309
00310 PyObject* Application::sGetDocument(PyObject * , PyObject *args,PyObject * )
00311 {
00312 char *pstr=0;
00313 if (!PyArg_ParseTuple(args, "s", &pstr))
00314 return NULL;
00315
00316 Document* doc = GetApplication().getDocument(pstr);
00317 if ( !doc ) {
00318 PyErr_Format(PyExc_NameError, "Unknown document '%s'", pstr);
00319 return 0L;
00320 }
00321
00322 return doc->getPyObject();
00323 }
00324
00325 PyObject* Application::sGetParam(PyObject * , PyObject *args,PyObject * )
00326 {
00327 char *pstr=0;
00328 if (!PyArg_ParseTuple(args, "s", &pstr))
00329 return NULL;
00330
00331 PY_TRY {
00332 return GetPyObject(GetApplication().GetParameterGroupByPath(pstr));
00333 }PY_CATCH;
00334 }
00335
00336
00337 PyObject* Application::sGetConfig(PyObject * , PyObject *args,PyObject * )
00338 {
00339 char *pstr;
00340
00341 if (!PyArg_ParseTuple(args, "s", &pstr))
00342 return NULL;
00343 const std::map<std::string, std::string>& Map = GetApplication().Config();
00344
00345 std::map<std::string, std::string>::const_iterator it = Map.find(pstr);
00346 if (it != Map.end()) {
00347 return Py_BuildValue("s",it->second.c_str());
00348 }
00349 else {
00350
00351 return PyString_FromString("");
00352 }
00353 }
00354
00355 PyObject* Application::sDumpConfig(PyObject * , PyObject *args,PyObject * )
00356 {
00357 if (!PyArg_ParseTuple(args, "") )
00358 return NULL;
00359
00360 PyObject *dict = PyDict_New();
00361 for (std::map<std::string,std::string>::iterator It= GetApplication()._mConfig.begin();
00362 It!=GetApplication()._mConfig.end();It++) {
00363 PyDict_SetItemString(dict,It->first.c_str(), PyString_FromString(It->second.c_str()));
00364 }
00365 return dict;
00366 }
00367
00368 PyObject* Application::sSetConfig(PyObject * , PyObject *args,PyObject * )
00369 {
00370 char *pstr,*pstr2;
00371
00372 if (!PyArg_ParseTuple(args, "ss", &pstr,&pstr2))
00373 return NULL;
00374
00375 GetApplication()._mConfig[pstr] = pstr2;
00376
00377 Py_INCREF(Py_None);
00378 return Py_None;
00379 }
00380
00381 PyObject* Application::sGetVersion(PyObject * , PyObject *args,PyObject * )
00382 {
00383 if (!PyArg_ParseTuple(args, ""))
00384 return NULL;
00385
00386 PyObject* pList = PyList_New(5);
00387 PyObject *pItem;
00388 pItem = PyString_FromString(Application::Config()["BuildVersionMajor"].c_str());
00389 PyList_SetItem(pList, 0, pItem);
00390 pItem = PyString_FromString(Application::Config()["BuildVersionMinor"].c_str());
00391 PyList_SetItem(pList, 1, pItem);
00392 pItem = PyString_FromString(Application::Config()["BuildRevision"].c_str());
00393 PyList_SetItem(pList, 2, pItem);
00394 pItem = PyString_FromString(Application::Config()["BuildRepositoryURL"].c_str());
00395 PyList_SetItem(pList, 4, pItem);
00396 pItem = PyString_FromString(Application::Config()["BuildCurrentDate"].c_str());
00397 PyList_SetItem(pList, 6, pItem);
00398
00399 return pList;
00400 }
00401
00402
00403 PyObject* Application::sAddImportType(PyObject * , PyObject *args,PyObject * )
00404 {
00405 char *psKey,*psMod;
00406
00407 if (!PyArg_ParseTuple(args, "ss", &psKey,&psMod))
00408 return NULL;
00409
00410 GetApplication().addImportType(psKey,psMod);
00411
00412 Py_Return;
00413 }
00414
00415 PyObject* Application::sGetImportType(PyObject * , PyObject *args,PyObject * )
00416 {
00417 char* psKey=0;
00418
00419 if (!PyArg_ParseTuple(args, "|s", &psKey))
00420 return NULL;
00421
00422 if (psKey) {
00423 Py::List list;
00424 std::vector<std::string> modules = GetApplication().getImportModules(psKey);
00425 for (std::vector<std::string>::iterator it = modules.begin(); it != modules.end(); ++it) {
00426 list.append(Py::String(*it));
00427 }
00428
00429 return Py::new_reference_to(list);
00430 }
00431 else {
00432 Py::Dict dict;
00433 std::vector<std::string> types = GetApplication().getImportTypes();
00434 for (std::vector<std::string>::iterator it = types.begin(); it != types.end(); ++it) {
00435 std::vector<std::string> modules = GetApplication().getImportModules(it->c_str());
00436 if (modules.empty()) {
00437 dict.setItem(it->c_str(), Py::None());
00438 }
00439 else if (modules.size() == 1) {
00440 dict.setItem(it->c_str(), Py::String(modules.front()));
00441 }
00442 else {
00443 Py::List list;
00444 for (std::vector<std::string>::iterator jt = modules.begin(); jt != modules.end(); ++jt) {
00445 list.append(Py::String(*jt));
00446 }
00447 dict.setItem(it->c_str(), list);
00448 }
00449 }
00450
00451 return Py::new_reference_to(dict);
00452 }
00453 }
00454
00455 PyObject* Application::sAddExportType(PyObject * , PyObject *args,PyObject * )
00456 {
00457 char *psKey,*psMod;
00458
00459 if (!PyArg_ParseTuple(args, "ss", &psKey,&psMod))
00460 return NULL;
00461
00462 GetApplication().addExportType(psKey,psMod);
00463
00464 Py_Return;
00465 }
00466
00467 PyObject* Application::sGetExportType(PyObject * , PyObject *args,PyObject * )
00468 {
00469 char* psKey=0;
00470
00471 if (!PyArg_ParseTuple(args, "|s", &psKey))
00472 return NULL;
00473
00474 if (psKey) {
00475 Py::List list;
00476 std::vector<std::string> modules = GetApplication().getExportModules(psKey);
00477 for (std::vector<std::string>::iterator it = modules.begin(); it != modules.end(); ++it) {
00478 list.append(Py::String(*it));
00479 }
00480
00481 return Py::new_reference_to(list);
00482 }
00483 else {
00484 Py::Dict dict;
00485 std::vector<std::string> types = GetApplication().getExportTypes();
00486 for (std::vector<std::string>::iterator it = types.begin(); it != types.end(); ++it) {
00487 std::vector<std::string> modules = GetApplication().getExportModules(it->c_str());
00488 if (modules.empty()) {
00489 dict.setItem(it->c_str(), Py::None());
00490 }
00491 else if (modules.size() == 1) {
00492 dict.setItem(it->c_str(), Py::String(modules.front()));
00493 }
00494 else {
00495 Py::List list;
00496 for (std::vector<std::string>::iterator jt = modules.begin(); jt != modules.end(); ++jt) {
00497 list.append(Py::String(*jt));
00498 }
00499 dict.setItem(it->c_str(), list);
00500 }
00501 }
00502
00503 return Py::new_reference_to(dict);
00504 }
00505 }
00506
00507 PyObject* Application::sGetResourceDir(PyObject * , PyObject *args,PyObject * )
00508 {
00509 if (!PyArg_ParseTuple(args, ""))
00510 return NULL;
00511
00512 Py::String datadir(Application::getResourceDir());
00513 return Py::new_reference_to(datadir);
00514 }
00515
00516 PyObject* Application::sGetHomePath(PyObject * , PyObject *args,PyObject * )
00517 {
00518 if (!PyArg_ParseTuple(args, ""))
00519 return NULL;
00520
00521 Py::String homedir(GetApplication().GetHomePath());
00522 return Py::new_reference_to(homedir);
00523 }
00524
00525 PyObject* Application::sListDocuments(PyObject * , PyObject *args,PyObject * )
00526 {
00527 if (!PyArg_ParseTuple(args, ""))
00528 return NULL;
00529 PY_TRY {
00530 PyObject *pDict = PyDict_New();
00531 PyObject *pKey;
00532 Base::PyObjectBase* pValue;
00533
00534 for (std::map<std::string,Document*>::const_iterator It = GetApplication().DocMap.begin();
00535 It != GetApplication().DocMap.end();++It) {
00536 pKey = PyString_FromString(It->first.c_str());
00537
00538 pValue = static_cast<Base::PyObjectBase*>(It->second->getPyObject());
00539 PyDict_SetItem(pDict, pKey, pValue);
00540
00541 pValue->DecRef();
00542 }
00543
00544 return pDict;
00545 } PY_CATCH;
00546 }
00547
00548 PyObject* Application::sAddDocObserver(PyObject * , PyObject *args,PyObject * )
00549 {
00550 PyObject* o;
00551 if (!PyArg_ParseTuple(args, "O",&o))
00552 return NULL;
00553 PY_TRY {
00554 DocumentObserverPython::addObserver(Py::Object(o));
00555 Py_Return;
00556 } PY_CATCH;
00557 }
00558
00559 PyObject* Application::sRemoveDocObserver(PyObject * , PyObject *args,PyObject * )
00560 {
00561 PyObject* o;
00562 if (!PyArg_ParseTuple(args, "O",&o))
00563 return NULL;
00564 PY_TRY {
00565 DocumentObserverPython::removeObserver(Py::Object(o));
00566 Py_Return;
00567 } PY_CATCH;
00568 }