diff --git a/src/Mod/Path/App/AppPath.cpp b/src/Mod/Path/App/AppPath.cpp index b4fc8f752..ab6ffe02e 100644 --- a/src/Mod/Path/App/AppPath.cpp +++ b/src/Mod/Path/App/AppPath.cpp @@ -42,25 +42,22 @@ #include "FeaturePathCompound.h" #include "FeaturePathShape.h" -extern struct PyMethodDef Path_methods[]; - -PyDoc_STRVAR(module_Path_doc, -"This module is the Path module."); - +namespace Path { +extern PyObject* initModule(); +} /* Python entry */ -extern "C" { -void PathExport initPath() +PyMODINIT_FUNC initPath() { - PyObject* pathModule = Py_InitModule3("Path", Path_methods, module_Path_doc); /* mod name, table ptr */ + PyObject* pathModule = Path::initModule(); Base::Console().Log("Loading Path module... done\n"); // Add Types to module - Base::Interpreter().addType(&Path::CommandPy ::Type,pathModule,"Command"); - Base::Interpreter().addType(&Path::PathPy ::Type,pathModule,"Path"); - Base::Interpreter().addType(&Path::ToolPy ::Type,pathModule,"Tool"); - Base::Interpreter().addType(&Path::TooltablePy ::Type,pathModule,"Tooltable"); + Base::Interpreter().addType(&Path::CommandPy ::Type, pathModule, "Command"); + Base::Interpreter().addType(&Path::PathPy ::Type, pathModule, "Path"); + Base::Interpreter().addType(&Path::ToolPy ::Type, pathModule, "Tool"); + Base::Interpreter().addType(&Path::TooltablePy ::Type, pathModule, "Tooltable"); // NOTE: To finish the initialization of our own type objects we must // call PyType_Ready, otherwise we run into a segmentation fault, later on. @@ -78,5 +75,3 @@ void PathExport initPath() Path::FeatureShape ::init(); Path::FeatureShapePython ::init(); } - -} // extern "C" diff --git a/src/Mod/Path/App/AppPathPy.cpp b/src/Mod/Path/App/AppPathPy.cpp index 833144fd3..b2d167cac 100644 --- a/src/Mod/Path/App/AppPathPy.cpp +++ b/src/Mod/Path/App/AppPathPy.cpp @@ -26,6 +26,9 @@ # include #endif +#include +#include + #include #include #include @@ -40,103 +43,125 @@ #include "FeaturePath.h" #include "FeaturePathCompound.h" -using namespace Path; - - -static PyObject * write (PyObject *self, PyObject *args) +namespace Path { +class Module : public Py::ExtensionModule { - char* Name; - PyObject* pObj; - if (!PyArg_ParseTuple(args, "Oet",&pObj,"utf-8",&Name)) - return NULL; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - Base::FileInfo file(EncodedName.c_str()); - - if (PyObject_TypeCheck(pObj, &(App::DocumentObjectPy::Type))) { - App::DocumentObject* obj = static_cast(pObj)->getDocumentObjectPtr(); - if (obj->getTypeId().isDerivedFrom(Base::Type::fromName("Path::Feature"))) { - const Toolpath& path = static_cast(obj)->Path.getValue(); - std::string gcode = path.toGCode(); - std::ofstream ofile(EncodedName.c_str()); - ofile << gcode; - ofile.close(); - } else - Py_Error(Base::BaseExceptionFreeCADError, "The given file is not a path"); +public: + Module() : Py::ExtensionModule("Path") + { + add_varargs_method("write",&Module::write, + "write(object,filename): Exports a given path object to a GCode file" + ); + add_varargs_method("read",&Module::read, + "read(filename,[document]): Imports a GCode file into the given document" + ); + add_varargs_method("show",&Module::show, + "show(path): Add the path to the active document or create one if no document exists" + ); + initialize("This module is the Path module."); // register with Python } - Py_Return; -} + virtual ~Module() {} -static PyObject * read (PyObject *self, PyObject *args) -{ - char* Name; - const char* DocName=0; - if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName)) - return NULL; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - - Base::FileInfo file(EncodedName.c_str()); - if (!file.exists()) - Py_Error(Base::BaseExceptionFreeCADError, "File doesn't exist"); - App::Document *pcDoc; - if (DocName) - pcDoc = App::GetApplication().getDocument(DocName); - else - pcDoc = App::GetApplication().getActiveDocument(); - if (!pcDoc) - pcDoc = App::GetApplication().newDocument(DocName); - - PY_TRY { - // read the gcode file - std::ifstream filestr(file.filePath().c_str()); - std::stringstream buffer; - buffer << filestr.rdbuf(); - std::string gcode = buffer.str(); - Toolpath path; - path.setFromGCode(gcode); - Path::Feature *object = static_cast(pcDoc->addObject("Path::Feature",file.fileNamePure().c_str())); - object->Path.setValue(path); - pcDoc->recompute(); - } PY_CATCH; - Py_Return; -} - - -static PyObject * show (PyObject *self, PyObject *args) -{ - PyObject *pcObj; - if (!PyArg_ParseTuple(args, "O!", &(PathPy::Type), &pcObj)) // convert args: Python->C - return NULL; // NULL triggers exception - - PY_TRY { - App::Document *pcDoc = App::GetApplication().getActiveDocument(); - if (!pcDoc) - pcDoc = App::GetApplication().newDocument(); - PathPy* pPath = static_cast(pcObj); - Path::Feature *pcFeature = (Path::Feature *)pcDoc->addObject("Path::Feature", "Path"); - Path::Toolpath* pa = pPath->getToolpathPtr(); - if (!pa) { - PyErr_SetString(PyExc_ReferenceError, - "object doesn't reference a valid path"); - return 0; +private: + Py::Object write(const Py::Tuple& args) + { + char* Name; + PyObject* pObj; + if (!PyArg_ParseTuple(args.ptr(), "Oet",&pObj,"utf-8",&Name)) + throw Py::Exception(); + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + Base::FileInfo file(EncodedName.c_str()); + + if (PyObject_TypeCheck(pObj, &(App::DocumentObjectPy::Type))) { + App::DocumentObject* obj = static_cast(pObj)->getDocumentObjectPtr(); + if (obj->getTypeId().isDerivedFrom(Base::Type::fromName("Path::Feature"))) { + const Toolpath& path = static_cast(obj)->Path.getValue(); + std::string gcode = path.toGCode(); + std::ofstream ofile(EncodedName.c_str()); + ofile << gcode; + ofile.close(); + } + else { + throw Py::RuntimeError("The given file is not a path"); + } } - // copy the data - pcFeature->Path.setValue(*pa); - } PY_CATCH; - Py_Return; + return Py::None(); + } + + Py::Object read(const Py::Tuple& args) + { + char* Name; + const char* DocName=0; + if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) + throw Py::Exception(); + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + + Base::FileInfo file(EncodedName.c_str()); + if (!file.exists()) + throw Py::RuntimeError("File doesn't exist"); + + App::Document *pcDoc; + if (DocName) + pcDoc = App::GetApplication().getDocument(DocName); + else + pcDoc = App::GetApplication().getActiveDocument(); + if (!pcDoc) + pcDoc = App::GetApplication().newDocument(DocName); + + try { + // read the gcode file + std::ifstream filestr(file.filePath().c_str()); + std::stringstream buffer; + buffer << filestr.rdbuf(); + std::string gcode = buffer.str(); + Toolpath path; + path.setFromGCode(gcode); + Path::Feature *object = static_cast(pcDoc->addObject("Path::Feature",file.fileNamePure().c_str())); + object->Path.setValue(path); + pcDoc->recompute(); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + + return Py::None(); + } + + Py::Object show(const Py::Tuple& args) + { + PyObject *pcObj; + if (!PyArg_ParseTuple(args.ptr(), "O!", &(PathPy::Type), &pcObj)) + throw Py::Exception(); + + try { + App::Document *pcDoc = App::GetApplication().getActiveDocument(); + if (!pcDoc) + pcDoc = App::GetApplication().newDocument(); + PathPy* pPath = static_cast(pcObj); + Path::Feature *pcFeature = (Path::Feature *)pcDoc->addObject("Path::Feature", "Path"); + Path::Toolpath* pa = pPath->getToolpathPtr(); + if (!pa) { + throw Py::Exception(PyExc_ReferenceError, "object doesn't reference a valid path"); + } + + // copy the data + pcFeature->Path.setValue(*pa); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + + return Py::None(); + } +}; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); } - -/* registration table */ -struct PyMethodDef Path_methods[] = { - {"write" ,write ,METH_VARARGS, - "write(object,filename): Exports a given path object to a GCode file"}, - {"read" ,read ,METH_VARARGS, - "read(filename,[document]): Imports a GCode file into the given document"}, - {"show" ,show ,METH_VARARGS, - "show(path): Add the path to the active document or create one if no document exists."}, - {NULL, NULL} /* end of table marker */ -}; +} // namespace Path diff --git a/src/Mod/Path/Gui/AppPathGui.cpp b/src/Mod/Path/Gui/AppPathGui.cpp index 3d10c27f1..74fe4ce62 100644 --- a/src/Mod/Path/Gui/AppPathGui.cpp +++ b/src/Mod/Path/Gui/AppPathGui.cpp @@ -46,13 +46,12 @@ void loadPathResource() Gui::Translator::instance()->refresh(); } -/* registration table */ -extern struct PyMethodDef PathGui_methods[]; - +namespace PathGui { +extern PyObject* initModule(); +} /* Python entry */ -extern "C" { -void PathGuiExport initPathGui() +PyMODINIT_FUNC initPathGui() { if (!Gui::Application::Instance) { PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application."); @@ -65,7 +64,7 @@ void PathGuiExport initPathGui() PyErr_SetString(PyExc_ImportError, e.what()); return; } - (void) Py_InitModule("PathGui", PathGui_methods); /* mod name, table ptr */ + (void)PathGui::initModule(); Base::Console().Log("Loading GUI of Path module... done\n"); // instantiating the commands @@ -84,5 +83,3 @@ void PathGuiExport initPathGui() // register preferences pages new Gui::PrefPageProducer ("Path"); } - -} // extern "C" { diff --git a/src/Mod/Path/Gui/AppPathGuiPy.cpp b/src/Mod/Path/Gui/AppPathGuiPy.cpp index a956ae58c..6fd3e6e9a 100644 --- a/src/Mod/Path/Gui/AppPathGuiPy.cpp +++ b/src/Mod/Path/Gui/AppPathGuiPy.cpp @@ -25,6 +25,9 @@ # include #endif +#include +#include + #include #include @@ -43,215 +46,248 @@ #include "DlgProcessorChooser.h" #include "ui_DlgProcessorChooser.h" -using namespace PathGui; - -static PyObject * open(PyObject *self, PyObject *args) +namespace PathGui { +class Module : public Py::ExtensionModule { - char* Name; - if (!PyArg_ParseTuple(args, "et","utf-8",&Name)) - return NULL; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - Base::FileInfo fi(EncodedName); - if (!fi.exists()) - Py_Error(Base::BaseExceptionFreeCADError, "File not found"); - Gui::WaitCursor wc; - wc.restoreCursor(); +public: + Module() : Py::ExtensionModule("PathGui") + { + add_varargs_method("open",&Module::open, + "open(filename): Opens a GCode file as a new document" + ); + add_varargs_method("insert",&Module::insert, + "insert(filename,docname): Imports a given GCode file into the given document" + ); + add_varargs_method("export",&Module::exporter, + "export(objectslist,filename): Exports a given list of Path objects to a GCode file" + ); + initialize("This module is the PathGui module."); // register with Python + } - PY_TRY { - std::string path = App::GetApplication().getHomePath(); - path += "Mod/Path/PathScripts/"; - QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_pre.py")); - std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") - ->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str()); - QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromLatin1("*_pre.py")); - QFileInfoList list = dir1.entryInfoList(); - list << dir2.entryInfoList(); - std::vector scripts; - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - scripts.push_back(fileInfo.baseName().toStdString()); - } - std::string selected; - PathGui::DlgProcessorChooser Dlg(scripts); - if (Dlg.exec() != QDialog::Accepted) { - Py_Return; - } - selected = Dlg.getSelected(); - - std::ostringstream pre; - std::ostringstream cmd; - if (selected.empty()) { - App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); - Gui::Command::runCommand(Gui::Command::Gui,"import Path"); - cmd << "Path.read(\"" << EncodedName << "\",\"" << pcDoc->getName() << "\")"; - Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); - } else { + virtual ~Module() {} + +private: + Py::Object open(const Py::Tuple& args) + { + char* Name; + if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name)) + throw Py::Exception(); + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + Base::FileInfo fi(EncodedName); + if (!fi.exists()) + throw Py::RuntimeError("File not found"); + + Gui::WaitCursor wc; + wc.restoreCursor(); + + try { + std::string path = App::GetApplication().getHomePath(); + path += "Mod/Path/PathScripts/"; + QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_pre.py")); + std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") + ->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str()); + QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromLatin1("*_pre.py")); + QFileInfoList list = dir1.entryInfoList(); + list << dir2.entryInfoList(); + std::vector scripts; for (int i = 0; i < list.size(); ++i) { QFileInfo fileInfo = list.at(i); - if (fileInfo.baseName().toStdString() == selected) { - if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) { - pre << "from PathScripts import " << selected; - } else { - pre << "import " << selected; - } - Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str()); - cmd << selected << ".open(\"" << EncodedName << "\")"; - Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); - } + scripts.push_back(fileInfo.baseName().toStdString()); } - } - } PY_CATCH; - Py_Return; -} - -static PyObject * importer(PyObject *self, PyObject *args) -{ - char* Name; - char* DocName=0; - if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName)) - return NULL; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - Base::FileInfo fi(EncodedName); - if (!fi.exists()) - Py_Error(Base::BaseExceptionFreeCADError, "File not found"); - Gui::WaitCursor wc; - wc.restoreCursor(); - - PY_TRY { - std::string path = App::GetApplication().getHomePath(); - path += "Mod/Path/PathScripts/"; - QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_pre.py")); - std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") - ->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str()); - QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromLatin1("*_pre.py")); - QFileInfoList list = dir1.entryInfoList(); - list << dir2.entryInfoList(); - std::vector scripts; - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - scripts.push_back(fileInfo.baseName().toStdString()); - } - std::string selected; - PathGui::DlgProcessorChooser Dlg(scripts); - if (Dlg.exec() != QDialog::Accepted) { - Py_Return; - } - selected = Dlg.getSelected(); - - App::Document *pcDoc = 0; - if (DocName) - pcDoc = App::GetApplication().getDocument(DocName); - else - pcDoc = App::GetApplication().getActiveDocument(); - - if (!pcDoc) { - pcDoc = App::GetApplication().newDocument(DocName); - } - - std::ostringstream pre; - std::ostringstream cmd; - if (selected.empty()) { - Gui::Command::runCommand(Gui::Command::Gui,"import Path"); - cmd << "Path.read(\"" << EncodedName << "\",\"" << pcDoc->getName() << "\")"; - Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); - } else { - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - if (fileInfo.baseName().toStdString() == selected) { - if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) { - pre << "from PathScripts import " << selected; - } else { - pre << "import " << selected; - } - Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str()); - cmd << selected << ".insert(\"" << EncodedName << "\",\"" << pcDoc->getName() << "\")"; - Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); - } + std::string selected; + PathGui::DlgProcessorChooser Dlg(scripts); + if (Dlg.exec() != QDialog::Accepted) { + return Py::None(); } - } - } PY_CATCH; - Py_Return; -} - -static PyObject * exporter(PyObject *self, PyObject *args) -{ - PyObject* object; - char* Name; - if (!PyArg_ParseTuple(args, "Oet",&object,"utf-8",&Name)) - return NULL; - std::string EncodedName = std::string(Name); - PyMem_Free(Name); - Gui::WaitCursor wc; - wc.restoreCursor(); - - PY_TRY { - Py::Sequence objlist(object); - if (objlist.size() == 0) - Py_Error(Base::BaseExceptionFreeCADError, "No object to export"); - std::string path = App::GetApplication().getHomePath(); - path += "Mod/Path/PathScripts/"; - QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_post.py")); - std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") - ->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str()); - QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromLatin1("*_post.py")); - QFileInfoList list = dir1.entryInfoList(); - list << dir2.entryInfoList(); - std::vector scripts; - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - scripts.push_back(fileInfo.baseName().toStdString()); - } - std::string selected; - PathGui::DlgProcessorChooser Dlg(scripts); - if (Dlg.exec() != QDialog::Accepted) { - Py_Return; - } - selected = Dlg.getSelected(); - - std::ostringstream pre; - std::ostringstream cmd; - if (selected.empty()) { - if (objlist.size() > 1) { - Py_Error(Base::BaseExceptionFreeCADError, "Cannot export more than one object without using a post script"); - } - PyObject* item = objlist[0].ptr(); - if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { - App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); - App::Document* doc = obj->getDocument(); + selected = Dlg.getSelected(); + + std::ostringstream pre; + std::ostringstream cmd; + if (selected.empty()) { + App::Document *pcDoc = App::GetApplication().newDocument("Unnamed"); Gui::Command::runCommand(Gui::Command::Gui,"import Path"); - cmd << "Path.write(FreeCAD.getDocument(\"" << doc->getName() << "\").getObject(\"" << obj->getNameInDocument() << "\"),\"" << EncodedName << "\")"; + cmd << "Path.read(\"" << EncodedName << "\",\"" << pcDoc->getName() << "\")"; Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); } else { - Py_Return; - } - } else { - for (int i = 0; i < list.size(); ++i) { - QFileInfo fileInfo = list.at(i); - if (fileInfo.baseName().toStdString() == selected) { - if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) { - pre << "from PathScripts import " << selected; - } else { - pre << "import " << selected; + for (int i = 0; i < list.size(); ++i) { + QFileInfo fileInfo = list.at(i); + if (fileInfo.baseName().toStdString() == selected) { + if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) { + pre << "from PathScripts import " << selected; + } else { + pre << "import " << selected; + } + Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str()); + cmd << selected << ".open(\"" << EncodedName << "\")"; + Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); } - Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str()); - cmd << selected << ".export(__objs__,\"" << EncodedName << "\")"; - Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); } } } - } PY_CATCH; - Py_Return; + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + + return Py::None(); + } + + Py::Object insert(const Py::Tuple& args) + { + char* Name; + char* DocName=0; + if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) + throw Py::Exception(); + + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + Base::FileInfo fi(EncodedName); + if (!fi.exists()) + throw Py::RuntimeError("File not found"); + + Gui::WaitCursor wc; + wc.restoreCursor(); + + try { + std::string path = App::GetApplication().getHomePath(); + path += "Mod/Path/PathScripts/"; + QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_pre.py")); + std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") + ->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str()); + QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromLatin1("*_pre.py")); + QFileInfoList list = dir1.entryInfoList(); + list << dir2.entryInfoList(); + std::vector scripts; + for (int i = 0; i < list.size(); ++i) { + QFileInfo fileInfo = list.at(i); + scripts.push_back(fileInfo.baseName().toStdString()); + } + std::string selected; + PathGui::DlgProcessorChooser Dlg(scripts); + if (Dlg.exec() != QDialog::Accepted) { + return Py::None(); + } + selected = Dlg.getSelected(); + + App::Document *pcDoc = 0; + if (DocName) + pcDoc = App::GetApplication().getDocument(DocName); + else + pcDoc = App::GetApplication().getActiveDocument(); + + if (!pcDoc) { + pcDoc = App::GetApplication().newDocument(DocName); + } + + std::ostringstream pre; + std::ostringstream cmd; + if (selected.empty()) { + Gui::Command::runCommand(Gui::Command::Gui,"import Path"); + cmd << "Path.read(\"" << EncodedName << "\",\"" << pcDoc->getName() << "\")"; + Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); + } else { + for (int i = 0; i < list.size(); ++i) { + QFileInfo fileInfo = list.at(i); + if (fileInfo.baseName().toStdString() == selected) { + if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) { + pre << "from PathScripts import " << selected; + } else { + pre << "import " << selected; + } + Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str()); + cmd << selected << ".insert(\"" << EncodedName << "\",\"" << pcDoc->getName() << "\")"; + Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); + } + } + } + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + + return Py::None(); + } + + Py::Object exporter(const Py::Tuple& args) + { + PyObject* object; + char* Name; + if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name)) + throw Py::Exception(); + + std::string EncodedName = std::string(Name); + PyMem_Free(Name); + Gui::WaitCursor wc; + wc.restoreCursor(); + + try { + Py::Sequence objlist(object); + if (objlist.size() == 0) + throw Py::RuntimeError("No object to export"); + + std::string path = App::GetApplication().getHomePath(); + path += "Mod/Path/PathScripts/"; + QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_post.py")); + std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro") + ->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str()); + QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromLatin1("*_post.py")); + QFileInfoList list = dir1.entryInfoList(); + list << dir2.entryInfoList(); + std::vector scripts; + for (int i = 0; i < list.size(); ++i) { + QFileInfo fileInfo = list.at(i); + scripts.push_back(fileInfo.baseName().toStdString()); + } + std::string selected; + PathGui::DlgProcessorChooser Dlg(scripts); + if (Dlg.exec() != QDialog::Accepted) { + return Py::None(); + } + selected = Dlg.getSelected(); + + std::ostringstream pre; + std::ostringstream cmd; + if (selected.empty()) { + if (objlist.size() > 1) { + throw Py::RuntimeError("Cannot export more than one object without using a post script"); + } + PyObject* item = objlist[0].ptr(); + if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { + App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); + App::Document* doc = obj->getDocument(); + Gui::Command::runCommand(Gui::Command::Gui,"import Path"); + cmd << "Path.write(FreeCAD.getDocument(\"" << doc->getName() << "\").getObject(\"" << obj->getNameInDocument() << "\"),\"" << EncodedName << "\")"; + Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); + } else { + return Py::None(); + } + } else { + for (int i = 0; i < list.size(); ++i) { + QFileInfo fileInfo = list.at(i); + if (fileInfo.baseName().toStdString() == selected) { + if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) { + pre << "from PathScripts import " << selected; + } else { + pre << "import " << selected; + } + Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str()); + cmd << selected << ".export(__objs__,\"" << EncodedName << "\")"; + Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str()); + } + } + } + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + + return Py::None(); + } +}; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); } -/* registration table */ -struct PyMethodDef PathGui_methods[] = { - {"open" ,open ,METH_VARARGS, - "open(filename): Opens a GCode file as a new document"}, - {"insert" ,importer ,METH_VARARGS, - "insert(filename,docname): Imports a given GCode file into the given document"}, - {"export" ,exporter ,METH_VARARGS, - "export(objectslist,filename): Exports a given list of Path objects to a GCode file"}, - {NULL, NULL} /* end of table marker */ -}; +} // namespace PathGui