Files
create/src/Gui/ApplicationPy.cpp

1521 lines
52 KiB
C++

/***************************************************************************
* Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QApplication>
# include <qfileinfo.h>
# include <qdir.h>
# include <QPrinter>
# include <QFileInfo>
# include <Inventor/SoInput.h>
# include <Inventor/actions/SoGetPrimitiveCountAction.h>
# include <Inventor/nodes/SoSeparator.h>
#endif
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/TranscodingException.hpp>
#include <boost/regex.hpp>
#include "Action.h"
#include "Application.h"
#include "BitmapFactory.h"
#include "Command.h"
#include "Document.h"
#include "MainWindow.h"
#include "MainWindowPy.h"
#include "Macro.h"
#include "EditorView.h"
#include "PythonEditor.h"
#include "SoFCDB.h"
#include "View3DInventor.h"
#include "SplitView3DInventor.h"
#include "ViewProvider.h"
#include "WaitCursor.h"
#include "PythonWrapper.h"
#include "WidgetFactory.h"
#include "Workbench.h"
#include "WorkbenchManager.h"
#include "Language/Translator.h"
#include "DownloadManager.h"
#include "DlgPreferencesImp.h"
#include "DocumentObserverPython.h"
#include <App/DocumentObjectPy.h>
#include <App/DocumentPy.h>
#include <App/PropertyFile.h>
#include <Base/Interpreter.h>
#include <Base/Console.h>
#include <CXX/Objects.hxx>
#include <Inventor/MarkerBitmaps.h>
using namespace Gui;
// FCApplication Methods // Methods structure
PyMethodDef Application::Methods[] = {
{"activateWorkbench",(PyCFunction) Application::sActivateWorkbenchHandler, METH_VARARGS,
"activateWorkbench(string) -> None\n\n"
"Activate the workbench by name"},
{"addWorkbench", (PyCFunction) Application::sAddWorkbenchHandler, METH_VARARGS,
"addWorkbench(string, object) -> None\n\n"
"Add a workbench under a defined name."},
{"removeWorkbench", (PyCFunction) Application::sRemoveWorkbenchHandler, METH_VARARGS,
"removeWorkbench(string) -> None\n\n"
"Remove the workbench with name"},
{"getWorkbench", (PyCFunction) Application::sGetWorkbenchHandler, METH_VARARGS,
"getWorkbench(string) -> object\n\n"
"Get the workbench by its name"},
{"listWorkbenches", (PyCFunction) Application::sListWorkbenchHandlers, METH_VARARGS,
"listWorkbenches() -> list\n\n"
"Show a list of all workbenches"},
{"activeWorkbench", (PyCFunction) Application::sActiveWorkbenchHandler, METH_VARARGS,
"activeWorkbench() -> object\n\n"
"Return the active workbench object"},
{"addResourcePath", (PyCFunction) Application::sAddResPath, METH_VARARGS,
"addResourcePath(string) -> None\n\n"
"Add a new path to the system where to find resource files\n"
"like icons or localization files"},
{"addLanguagePath", (PyCFunction) Application::sAddLangPath, METH_VARARGS,
"addLanguagePath(string) -> None\n\n"
"Add a new path to the system where to find language files"},
{"addIconPath", (PyCFunction) Application::sAddIconPath, METH_VARARGS,
"addIconPath(string) -> None\n\n"
"Add a new path to the system where to find icon files"},
{"addIcon", (PyCFunction) Application::sAddIcon, METH_VARARGS,
"addIcon(string, string or list) -> None\n\n"
"Add an icon as file name or in XPM format to the system"},
{"getIcon", (PyCFunction) Application::sGetIcon, METH_VARARGS,
"getIcon(string) -> QIcon\n\n"
"Get an icon in the system"},
{"isIconCached", (PyCFunction) Application::sIsIconCached, METH_VARARGS,
"isIconCached(String) -> Bool\n\n"
"Check if an icon with the given name is cached"},
{"getMainWindow", (PyCFunction) Application::sGetMainWindow, METH_VARARGS,
"getMainWindow() -> QMainWindow\n\n"
"Return the main window instance"},
{"updateGui", (PyCFunction) Application::sUpdateGui, METH_VARARGS,
"updateGui() -> None\n\n"
"Update the main window and all its windows"},
{"updateLocale", (PyCFunction) Application::sUpdateLocale, METH_VARARGS,
"updateLocale() -> None\n\n"
"Update the localization"},
{"getLocale", (PyCFunction) Application::sGetLocale, METH_VARARGS,
"getLocale() -> string\n\n"
"Returns the locale currently used by FreeCAD"},
{"setLocale", (PyCFunction) Application::sSetLocale, METH_VARARGS,
"getLocale(string) -> None\n\n"
"Sets the locale used by FreeCAD. You can set it by\n"
"top-level domain (e.g. \"de\") or the language name (e.g. \"German\")"},
{"supportedLocales", (PyCFunction) Application::sSupportedLocales, METH_VARARGS,
"supportedLocales() -> dict\n\n"
"Returns a dict of all supported languages/top-level domains"},
{"createDialog", (PyCFunction) Application::sCreateDialog, METH_VARARGS,
"createDialog(string) -- Open a UI file"},
{"addPreferencePage", (PyCFunction) Application::sAddPreferencePage, METH_VARARGS,
"addPreferencePage(string,string) -- Add a UI form to the\n"
"preferences dialog. The first argument specifies the file name"
"and the second specifies the group name"},
{"addCommand", (PyCFunction) Application::sAddCommand, METH_VARARGS,
"addCommand(string, object) -> None\n\n"
"Add a command object"},
{"runCommand", (PyCFunction) Application::sRunCommand, METH_VARARGS,
"runCommand(string) -> None\n\n"
"Run command with name"},
{"SendMsgToActiveView", (PyCFunction) Application::sSendActiveView, METH_VARARGS,
"deprecated -- use class View"},
{"sendMsgToFocusView", (PyCFunction) Application::sSendFocusView, METH_VARARGS,
"send message to the focused view"},
{"hide", (PyCFunction) Application::sHide, METH_VARARGS,
"deprecated"},
{"show", (PyCFunction) Application::sShow, METH_VARARGS,
"deprecated"},
{"hideObject", (PyCFunction) Application::sHideObject, METH_VARARGS,
"hideObject(object) -> None\n\n"
"Hide the view provider to the given object"},
{"showObject", (PyCFunction) Application::sShowObject, METH_VARARGS,
"showObject(object) -> None\n\n"
"Show the view provider to the given object"},
{"open", (PyCFunction) Application::sOpen, METH_VARARGS,
"Open a macro, Inventor or VRML file"},
{"insert", (PyCFunction) Application::sInsert, METH_VARARGS,
"Open a macro, Inventor or VRML file"},
{"export", (PyCFunction) Application::sExport, METH_VARARGS,
"save scene to Inventor or VRML file"},
{"activeDocument", (PyCFunction) Application::sActiveDocument, METH_VARARGS,
"activeDocument() -> object or None\n\n"
"Return the active document or None if no one exists"},
{"setActiveDocument", (PyCFunction) Application::sSetActiveDocument, METH_VARARGS,
"setActiveDocument(string or App.Document) -> None\n\n"
"Activate the specified document"},
{"activeView", (PyCFunction)Application::sActiveView, METH_VARARGS,
"activeView(typename=None) -> object or None\n\n"
"Return the active view of the active document or None if no one exists" },
{"activateView", (PyCFunction)Application::sActivateView, METH_VARARGS,
"activateView(type)\n\n"
"Activate a view of the given type of the active document"},
{"editDocument", (PyCFunction)Application::sEditDocument, METH_VARARGS,
"editDocument() -> object or None\n\n"
"Return the current editing document or None if no one exists" },
{"getDocument", (PyCFunction) Application::sGetDocument, METH_VARARGS,
"getDocument(string) -> object\n\n"
"Get a document by its name"},
{"doCommand", (PyCFunction) Application::sDoCommand, METH_VARARGS,
"doCommand(string) -> None\n\n"
"Prints the given string in the python console and runs it"},
{"doCommandGui", (PyCFunction) Application::sDoCommandGui, METH_VARARGS,
"doCommandGui(string) -> None\n\n"
"Prints the given string in the python console and runs it but doesn't record it in macros"},
{"addModule", (PyCFunction) Application::sAddModule, METH_VARARGS,
"addModule(string) -> None\n\n"
"Prints the given module import only once in the macro recording"},
{"showDownloads", (PyCFunction) Application::sShowDownloads, METH_VARARGS,
"showDownloads() -> None\n\n"
"Shows the downloads manager window"},
{"showPreferences", (PyCFunction) Application::sShowPreferences, METH_VARARGS,
"showPreferences([string,int]) -> None\n\n"
"Shows the preferences window. If string and int are provided, the given page index in the given group is shown."},
{"createViewer", (PyCFunction) Application::sCreateViewer, METH_VARARGS,
"createViewer([int]) -> View3DInventor/SplitView3DInventor\n\n"
"shows and returns a viewer. If the integer argument is given and > 1: -> splitViewer"},
{"getMarkerIndex", (PyCFunction) Application::sGetMarkerIndex, METH_VARARGS,
"Get marker index according to marker size setting"},
{"addDocumentObserver", (PyCFunction) Application::sAddDocObserver, METH_VARARGS,
"addDocumentObserver() -> None\n\n"
"Add an observer to get notified about changes on documents."},
{"removeDocumentObserver", (PyCFunction) Application::sRemoveDocObserver, METH_VARARGS,
"removeDocumentObserver() -> None\n\n"
"Remove an added document observer."},
{"listUserEditModes", (PyCFunction) Application::sListUserEditModes, METH_VARARGS,
"listUserEditModes() -> list\n\n"
"List available user edit modes"},
{"getUserEditMode", (PyCFunction) Application::sGetUserEditMode, METH_VARARGS,
"getUserEditMode() -> string\n\n"
"Get current user edit mode"},
{"setUserEditMode", (PyCFunction) Application::sSetUserEditMode, METH_VARARGS,
"setUserEditMode(string=mode) -> Bool\n\n"
"Set user edit mode to 'mode', returns True if exists, false otherwise"},
{"reload", (PyCFunction) Application::sReload, METH_VARARGS,
"reload(name) -> doc\n\n"
"Reload a partial opened document"},
{"loadFile", (PyCFunction) Application::sLoadFile, METH_VARARGS,
"loadFile(string=filename,[string=module]) -> None\n\n"
"Loads an arbitrary file by delegating to the given Python module:\n"
"* If no module is given it will be determined by the file extension.\n"
"* If more than one module can load a file the first one will be taken.\n"
"* If no module exists to load the file an exception will be raised."},
{"coinRemoveAllChildren", (PyCFunction) Application::sCoinRemoveAllChildren, METH_VARARGS,
"Remove all children from a group node"},
{NULL, NULL, 0, NULL} /* Sentinel */
};
PyObject* Gui::Application::sEditDocument(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, "")) // convert args: Python->C
return NULL; // NULL triggers exception
Document *pcDoc = Instance->editDocument();
if (pcDoc) {
return pcDoc->getPyObject();
}
else {
Py_Return;
}
}
PyObject* Gui::Application::sActiveDocument(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
Document *pcDoc = Instance->activeDocument();
if (pcDoc) {
return pcDoc->getPyObject();
}
else {
Py_Return;
}
}
PyObject* Gui::Application::sActiveView(PyObject * /*self*/, PyObject *args)
{
const char *typeName=0;
if (!PyArg_ParseTuple(args, "|s", &typeName))
return NULL;
PY_TRY {
Base::Type type;
if(typeName) {
type = Base::Type::fromName(typeName);
if(type.isBad()) {
PyErr_Format(PyExc_TypeError, "Invalid type '%s'", typeName);
return 0;
}
}
Gui::MDIView* mdiView = Instance->activeView();
if (mdiView && (type.isBad() || mdiView->isDerivedFrom(type))) {
auto res = Py::asObject(mdiView->getPyObject());
if(!res.isNone() || !type.isBad())
return Py::new_reference_to(res);
}
if(type.isBad())
type = Gui::View3DInventor::getClassTypeId();
Instance->activateView(type, true);
mdiView = Instance->activeView();
if (mdiView)
return mdiView->getPyObject();
Py_Return;
} PY_CATCH
}
PyObject* Gui::Application::sActivateView(PyObject * /*self*/, PyObject *args)
{
char* typeStr;
PyObject *create = Py_False;
if (!PyArg_ParseTuple(args, "sO!", &typeStr, &PyBool_Type, &create))
return NULL;
Base::Type type = Base::Type::fromName(typeStr);
Instance->activateView(type, PyObject_IsTrue(create) ? true : false);
Py_Return;
}
PyObject* Gui::Application::sSetActiveDocument(PyObject * /*self*/, PyObject *args)
{
Document *pcDoc = 0;
do {
char *pstr=0;
if (PyArg_ParseTuple(args, "s", &pstr)) {
pcDoc = Instance->getDocument(pstr);
if (!pcDoc) {
PyErr_Format(PyExc_NameError, "Unknown document '%s'", pstr);
return 0;
}
break;
}
PyErr_Clear();
PyObject* doc;
if (PyArg_ParseTuple(args, "O!", &(App::DocumentPy::Type), &doc)) {
pcDoc = Instance->getDocument(static_cast<App::DocumentPy*>(doc)->getDocumentPtr());
if (!pcDoc) {
PyErr_Format(PyExc_KeyError, "Unknown document instance");
return 0;
}
break;
}
}
while(false);
if (!pcDoc) {
PyErr_SetString(PyExc_TypeError, "Either string or App.Document expected");
return 0;
}
if (Instance->activeDocument() != pcDoc) {
Gui::MDIView* view = pcDoc->getActiveView();
getMainWindow()->setActiveWindow(view);
}
Py_Return;
}
PyObject* Application::sGetDocument(PyObject * /*self*/, PyObject *args)
{
char *pstr=0;
if (PyArg_ParseTuple(args, "s", &pstr)) {
Document *pcDoc = Instance->getDocument(pstr);
if (!pcDoc) {
PyErr_Format(PyExc_NameError, "Unknown document '%s'", pstr);
return 0;
}
return pcDoc->getPyObject();
}
PyErr_Clear();
PyObject* doc;
if (PyArg_ParseTuple(args, "O!", &(App::DocumentPy::Type), &doc)) {
Document *pcDoc = Instance->getDocument(static_cast<App::DocumentPy*>(doc)->getDocumentPtr());
if (!pcDoc) {
PyErr_Format(PyExc_KeyError, "Unknown document instance");
return 0;
}
return pcDoc->getPyObject();
}
PyErr_SetString(PyExc_TypeError, "Either string or App.Document exprected");
return 0;
}
PyObject* Application::sHide(PyObject * /*self*/, PyObject *args)
{
char *psFeatStr;
if (!PyArg_ParseTuple(args, "s;Name of the object to hide has to be given!",&psFeatStr))
return NULL;
Document *pcDoc = Instance->activeDocument();
if (pcDoc)
pcDoc->setHide(psFeatStr);
Py_Return;
}
PyObject* Application::sShow(PyObject * /*self*/, PyObject *args)
{
char *psFeatStr;
if (!PyArg_ParseTuple(args, "s;Name of the object to show has to be given!",&psFeatStr))
return NULL;
Document *pcDoc = Instance->activeDocument();
if (pcDoc)
pcDoc->setShow(psFeatStr);
Py_Return;
}
PyObject* Application::sHideObject(PyObject * /*self*/, PyObject *args)
{
PyObject *object;
if (!PyArg_ParseTuple(args, "O!",&(App::DocumentObjectPy::Type),&object))
return 0;
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(object)->getDocumentObjectPtr();
Instance->hideViewProvider(obj);
Py_Return;
}
PyObject* Application::sShowObject(PyObject * /*self*/, PyObject *args)
{
PyObject *object;
if (!PyArg_ParseTuple(args, "O!",&(App::DocumentObjectPy::Type),&object))
return 0;
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(object)->getDocumentObjectPtr();
Instance->showViewProvider(obj);
Py_Return;
}
PyObject* Application::sOpen(PyObject * /*self*/, PyObject *args)
{
// only used to open Python files
char* Name;
if (!PyArg_ParseTuple(args, "et","utf-8",&Name))
return NULL;
std::string Utf8Name = std::string(Name);
PyMem_Free(Name);
PY_TRY {
QString fileName = QString::fromUtf8(Utf8Name.c_str());
QFileInfo fi;
fi.setFile(fileName);
QString ext = fi.suffix().toLower();
QList<EditorView*> views = getMainWindow()->findChildren<EditorView*>();
for (QList<EditorView*>::Iterator it = views.begin(); it != views.end(); ++it) {
if ((*it)->fileName() == fileName) {
(*it)->setFocus();
Py_Return;
}
}
if (ext == QLatin1String("iv")) {
if (!Application::Instance->activeDocument())
App::GetApplication().newDocument();
//QString cmd = QString("Gui.activeDocument().addAnnotation(\"%1\",\"%2\")").arg(fi.baseName()).arg(fi.absoluteFilePath());
QString cmd = QString::fromLatin1(
"App.ActiveDocument.addObject(\"App::InventorObject\",\"%1\")."
"FileName=\"%2\"\n"
"App.ActiveDocument.ActiveObject.Label=\"%1\"\n"
"App.ActiveDocument.recompute()")
.arg(fi.baseName(), fi.absoluteFilePath());
Base::Interpreter().runString(cmd.toUtf8());
}
else if (ext == QLatin1String("wrl") ||
ext == QLatin1String("vrml") ||
ext == QLatin1String("wrz")) {
if (!Application::Instance->activeDocument())
App::GetApplication().newDocument();
// Add this to the search path in order to read inline files (#0002029)
QByteArray path = fi.absolutePath().toUtf8();
SoInput::addDirectoryFirst(path.constData());
//QString cmd = QString("Gui.activeDocument().addAnnotation(\"%1\",\"%2\")").arg(fi.baseName()).arg(fi.absoluteFilePath());
QString cmd = QString::fromLatin1(
"App.ActiveDocument.addObject(\"App::VRMLObject\",\"%1\")."
"VrmlFile=\"%2\"\n"
"App.ActiveDocument.ActiveObject.Label=\"%1\"\n"
"App.ActiveDocument.recompute()")
.arg(fi.baseName(), fi.absoluteFilePath());
Base::Interpreter().runString(cmd.toUtf8());
SoInput::removeDirectory(path.constData());
}
else if (ext == QLatin1String("py") || ext == QLatin1String("fcmacro") ||
ext == QLatin1String("fcscript")) {
PythonEditor* editor = new PythonEditor();
editor->setWindowIcon(Gui::BitmapFactory().iconFromTheme("applications-python"));
PythonEditorView* edit = new PythonEditorView(editor, getMainWindow());
edit->open(fileName);
edit->resize(400, 300);
getMainWindow()->addWindow( edit );
}
else {
Base::Console().Error("File type '%s' not supported\n", ext.toLatin1().constData());
}
} PY_CATCH;
Py_Return;
}
PyObject* Application::sInsert(PyObject * /*self*/, PyObject *args)
{
char* Name;
char* DocName=0;
if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName))
return NULL;
std::string Utf8Name = std::string(Name);
PyMem_Free(Name);
PY_TRY {
QString fileName = QString::fromUtf8(Utf8Name.c_str());
QFileInfo fi;
fi.setFile(fileName);
QString ext = fi.suffix().toLower();
if (ext == QLatin1String("iv")) {
App::Document *doc = 0;
if (DocName)
doc = App::GetApplication().getDocument(DocName);
else
doc = App::GetApplication().getActiveDocument();
if (!doc)
doc = App::GetApplication().newDocument(DocName);
App::DocumentObject* obj = doc->addObject("App::InventorObject",
(const char*)fi.baseName().toUtf8());
obj->Label.setValue((const char*)fi.baseName().toUtf8());
static_cast<App::PropertyString*>(obj->getPropertyByName("FileName"))
->setValue((const char*)fi.absoluteFilePath().toUtf8());
doc->recompute();
}
else if (ext == QLatin1String("wrl") ||
ext == QLatin1String("vrml") ||
ext == QLatin1String("wrz")) {
App::Document *doc = 0;
if (DocName)
doc = App::GetApplication().getDocument(DocName);
else
doc = App::GetApplication().getActiveDocument();
if (!doc)
doc = App::GetApplication().newDocument(DocName);
// Add this to the search path in order to read inline files (#0002029)
QByteArray path = fi.absolutePath().toUtf8();
SoInput::addDirectoryFirst(path.constData());
App::DocumentObject* obj = doc->addObject("App::VRMLObject",
(const char*)fi.baseName().toUtf8());
obj->Label.setValue((const char*)fi.baseName().toUtf8());
static_cast<App::PropertyFileIncluded*>(obj->getPropertyByName("VrmlFile"))
->setValue((const char*)fi.absoluteFilePath().toUtf8());
doc->recompute();
SoInput::removeDirectory(path.constData());
}
else if (ext == QLatin1String("py") || ext == QLatin1String("fcmacro") ||
ext == QLatin1String("fcscript")) {
PythonEditor* editor = new PythonEditor();
editor->setWindowIcon(Gui::BitmapFactory().iconFromTheme("applications-python"));
PythonEditorView* edit = new PythonEditorView(editor, getMainWindow());
edit->open(fileName);
edit->resize(400, 300);
getMainWindow()->addWindow( edit );
}
else {
Base::Console().Error("File type '%s' not supported\n", ext.toLatin1().constData());
}
} PY_CATCH;
Py_Return;
}
PyObject* Application::sExport(PyObject * /*self*/, PyObject *args)
{
PyObject* object;
char* Name;
if (!PyArg_ParseTuple(args, "Oet",&object,"utf-8",&Name))
return NULL;
std::string Utf8Name = std::string(Name);
PyMem_Free(Name);
PY_TRY {
App::Document* doc = 0;
Py::Sequence list(object);
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
doc = obj->getDocument();
break;
}
}
QString fileName = QString::fromUtf8(Utf8Name.c_str());
QFileInfo fi;
fi.setFile(fileName);
QString ext = fi.suffix().toLower();
if (ext == QLatin1String("iv") ||
ext == QLatin1String("wrl") ||
ext == QLatin1String("vrml") ||
ext == QLatin1String("wrz") ||
ext == QLatin1String("x3d") ||
ext == QLatin1String("x3dz") ||
ext == QLatin1String("xhtml")) {
// build up the graph
SoSeparator* sep = new SoSeparator();
sep->ref();
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(obj);
if (vp) {
sep->addChild(vp->getRoot());
}
}
}
SoGetPrimitiveCountAction action;
action.setCanApproximate(true);
action.apply(sep);
bool binary = false;
if (action.getTriangleCount() > 100000 ||
action.getPointCount() > 30000 ||
action.getLineCount() > 10000)
binary = true;
SoFCDB::writeToFile(sep, Utf8Name.c_str(), binary);
sep->unref();
}
else if (ext == QLatin1String("pdf")) {
// get the view that belongs to the found document
Gui::Document* gui_doc = Application::Instance->getDocument(doc);
if (gui_doc) {
Gui::MDIView* view = gui_doc->getActiveView();
if (view) {
View3DInventor* view3d = qobject_cast<View3DInventor*>(view);
if (view3d)
view3d->viewAll();
QPrinter printer(QPrinter::ScreenResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
view->print(&printer);
}
}
}
else {
Base::Console().Error("File type '%s' not supported\n", ext.toLatin1().constData());
}
} PY_CATCH;
Py_Return;
}
PyObject* Application::sSendActiveView(PyObject * /*self*/, PyObject *args)
{
char *psCommandStr;
PyObject *suppress=Py_False;
if (!PyArg_ParseTuple(args, "s|O!",&psCommandStr,&PyBool_Type,&suppress))
return NULL;
const char* ppReturn=0;
if (!Instance->sendMsgToActiveView(psCommandStr,&ppReturn)) {
if (!PyObject_IsTrue(suppress))
Base::Console().Warning("Unknown view command: %s\n",psCommandStr);
}
// Print the return value to the output
if (ppReturn) {
return Py_BuildValue("s",ppReturn);
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sSendFocusView(PyObject * /*self*/, PyObject *args)
{
char *psCommandStr;
PyObject *suppress=Py_False;
if (!PyArg_ParseTuple(args, "s|O!",&psCommandStr,&PyBool_Type,&suppress))
return NULL;
const char* ppReturn=0;
if (!Instance->sendMsgToFocusView(psCommandStr,&ppReturn)) {
if (!PyObject_IsTrue(suppress))
Base::Console().Warning("Unknown view command: %s\n",psCommandStr);
}
// Print the return value to the output
if (ppReturn) {
return Py_BuildValue("s",ppReturn);
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sGetMainWindow(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return nullptr;
try {
return Py::new_reference_to(MainWindowPy::createWrapper(Gui::getMainWindow()));
}
catch (const Py::Exception&) {
return nullptr;
}
}
PyObject* Application::sUpdateGui(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
qApp->processEvents();
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sUpdateLocale(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
Translator::instance()->refresh();
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sGetLocale(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
std::string locale = Translator::instance()->activeLanguage();
return PyUnicode_FromString(locale.c_str());
}
PyObject* Application::sSetLocale(PyObject * /*self*/, PyObject *args)
{
char* name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
std::string cname(name);
TStringMap map = Translator::instance()->supportedLocales();
map["English"] = "en";
for (const auto& it : map) {
if (it.first == cname || it.second == cname) {
Translator::instance()->activateLanguage(it.first.c_str());
break;
}
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sSupportedLocales(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
TStringMap map = Translator::instance()->supportedLocales();
Py::Dict dict;
dict.setItem(Py::String("English"), Py::String("en"));
for (const auto& it : map) {
Py::String key(it.first);
Py::String val(it.second);
dict.setItem(key, val);
}
return Py::new_reference_to(dict);
}
PyObject* Application::sCreateDialog(PyObject * /*self*/, PyObject *args)
{
char* fn = 0;
if (!PyArg_ParseTuple(args, "s", &fn))
return NULL;
PyObject* pPyResource=0L;
try{
pPyResource = new PyResource();
((PyResource*)pPyResource)->load(fn);
}
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_AssertionError, e.what());
return NULL;
}
return pPyResource;
}
PyObject* Application::sAddPreferencePage(PyObject * /*self*/, PyObject *args)
{
char *fn, *grp;
if (PyArg_ParseTuple(args, "ss", &fn,&grp)) {
QFileInfo fi(QString::fromUtf8(fn));
if (!fi.exists()) {
PyErr_SetString(PyExc_RuntimeError, "UI file does not exist");
return 0;
}
// add to the preferences dialog
new PrefPageUiProducer(fn, grp);
Py_INCREF(Py_None);
return Py_None;
}
PyErr_Clear();
PyObject* dlg;
// old style classes
if (PyArg_ParseTuple(args, "O!s", &PyType_Type, &dlg, &grp)) {
// add to the preferences dialog
new PrefPagePyProducer(Py::Object(dlg), grp);
Py_INCREF(Py_None);
return Py_None;
}
PyErr_Clear();
// new style classes
if (PyArg_ParseTuple(args, "O!s", &PyType_Type, &dlg, &grp)) {
// add to the preferences dialog
new PrefPagePyProducer(Py::Object(dlg), grp);
Py_INCREF(Py_None);
return Py_None;
}
return 0;
}
PyObject* Application::sActivateWorkbenchHandler(PyObject * /*self*/, PyObject *args)
{
char* psKey;
if (!PyArg_ParseTuple(args, "s", &psKey))
return NULL;
// search for workbench handler from the dictionary
PyObject* pcWorkbench = PyDict_GetItemString(Instance->_pcWorkbenchDictionary, psKey);
if (!pcWorkbench) {
PyErr_Format(PyExc_KeyError, "No such workbench '%s'", psKey);
return NULL;
}
try {
bool ok = Instance->activateWorkbench(psKey);
return Py::new_reference_to(Py::Boolean(ok));
}
catch (const Base::Exception& e) {
std::stringstream err;
err << psKey << ": " << e.what();
PyErr_SetString(Base::BaseExceptionFreeCADError, err.str().c_str());
return 0;
}
catch (const XERCES_CPP_NAMESPACE_QUALIFIER TranscodingException& e) {
std::stringstream err;
char *pMsg = XERCES_CPP_NAMESPACE_QUALIFIER XMLString::transcode(e.getMessage());
err << "Transcoding exception in Xerces-c:\n\n"
<< "Transcoding exception raised in activateWorkbench.\n"
<< "Check if your user configuration file is valid.\n"
<< " Exception message:"
<< pMsg;
XERCES_CPP_NAMESPACE_QUALIFIER XMLString::release(&pMsg);
PyErr_SetString(PyExc_RuntimeError, err.str().c_str());
return 0;
}
catch (...) {
std::stringstream err;
err << "Unknown C++ exception raised in activateWorkbench('" << psKey << "')";
PyErr_SetString(Base::BaseExceptionFreeCADError, err.str().c_str());
return 0;
}
}
PyObject* Application::sAddWorkbenchHandler(PyObject * /*self*/, PyObject *args)
{
PyObject* pcObject;
std::string item;
if (!PyArg_ParseTuple(args, "O", &pcObject))
return NULL;
try {
// get the class object 'Workbench' from the main module that is expected
// to be base class for all workbench classes
Py::Module module("__main__");
Py::Object baseclass(module.getAttr(std::string("Workbench")));
// check whether it is an instance or class object
Py::Object object(pcObject);
Py::String name;
if (PyObject_IsSubclass(object.ptr(), baseclass.ptr()) == 1) {
// create an instance of this class
name = object.getAttr(std::string("__name__"));
Py::Tuple arg;
Py::Callable creation(object);
object = creation.apply(arg);
}
else if (PyObject_IsInstance(object.ptr(), baseclass.ptr()) == 1) {
// extract the class name of the instance
PyErr_Clear(); // PyObject_IsSubclass set an exception
Py::Object classobj = object.getAttr(std::string("__class__"));
name = classobj.getAttr(std::string("__name__"));
}
else {
PyErr_SetString(PyExc_TypeError, "arg must be a subclass or an instance of "
"a subclass of 'Workbench'");
return NULL;
}
// Search for some methods and members without invoking them
Py::Callable(object.getAttr(std::string("Initialize")));
Py::Callable(object.getAttr(std::string("GetClassName")));
item = name.as_std_string("ascii");
PyObject* wb = PyDict_GetItemString(Instance->_pcWorkbenchDictionary,item.c_str());
if (wb) {
PyErr_Format(PyExc_KeyError, "'%s' already exists.", item.c_str());
return NULL;
}
PyDict_SetItemString(Instance->_pcWorkbenchDictionary,item.c_str(),object.ptr());
Instance->signalAddWorkbench(item.c_str());
}
catch (const Py::Exception&) {
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sRemoveWorkbenchHandler(PyObject * /*self*/, PyObject *args)
{
char* psKey;
if (!PyArg_ParseTuple(args, "s", &psKey))
return NULL;
PyObject* wb = PyDict_GetItemString(Instance->_pcWorkbenchDictionary,psKey);
if (!wb) {
PyErr_Format(PyExc_KeyError, "No such workbench '%s'", psKey);
return NULL;
}
Instance->signalRemoveWorkbench(psKey);
WorkbenchManager::instance()->removeWorkbench(psKey);
PyDict_DelItemString(Instance->_pcWorkbenchDictionary,psKey);
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sGetWorkbenchHandler(PyObject * /*self*/, PyObject *args)
{
char* psKey;
if (!PyArg_ParseTuple(args, "s", &psKey))
return NULL;
// get the python workbench object from the dictionary
PyObject* pcWorkbench = PyDict_GetItemString(Instance->_pcWorkbenchDictionary, psKey);
if (!pcWorkbench) {
PyErr_Format(PyExc_KeyError, "No such workbench '%s'", psKey);
return NULL;
}
Py_INCREF(pcWorkbench);
return pcWorkbench;
}
PyObject* Application::sListWorkbenchHandlers(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
Py_INCREF(Instance->_pcWorkbenchDictionary);
return Instance->_pcWorkbenchDictionary;
}
PyObject* Application::sActiveWorkbenchHandler(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
Workbench* actWb = WorkbenchManager::instance()->active();
if (!actWb) {
PyErr_SetString(PyExc_AssertionError, "No active workbench\n");
return NULL;
}
// get the python workbench object from the dictionary
std::string key = actWb->name();
PyObject* pcWorkbench = PyDict_GetItemString(Instance->_pcWorkbenchDictionary, key.c_str());
if (!pcWorkbench) {
PyErr_Format(PyExc_KeyError, "No such workbench '%s'", key.c_str());
return NULL;
}
// object get incremented
Py_INCREF(pcWorkbench);
return pcWorkbench;
}
PyObject* Application::sAddResPath(PyObject * /*self*/, PyObject *args)
{
char* filePath;
if (!PyArg_ParseTuple(args, "et", "utf-8", &filePath))
return NULL;
QString path = QString::fromUtf8(filePath);
PyMem_Free(filePath);
if (QDir::isRelativePath(path)) {
// Home path ends with '/'
QString home = QString::fromStdString(App::Application::getHomePath());
path = home + path;
}
BitmapFactory().addPath(path);
Translator::instance()->addPath(path);
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sAddLangPath(PyObject * /*self*/, PyObject *args)
{
char* filePath;
if (!PyArg_ParseTuple(args, "et", "utf-8", &filePath))
return NULL;
QString path = QString::fromUtf8(filePath);
PyMem_Free(filePath);
if (QDir::isRelativePath(path)) {
// Home path ends with '/'
QString home = QString::fromStdString(App::Application::getHomePath());
path = home + path;
}
Translator::instance()->addPath(path);
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sAddIconPath(PyObject * /*self*/, PyObject *args)
{
char* filePath;
if (!PyArg_ParseTuple(args, "et", "utf-8", &filePath))
return NULL;
QString path = QString::fromUtf8(filePath);
PyMem_Free(filePath);
if (QDir::isRelativePath(path)) {
// Home path ends with '/'
QString home = QString::fromStdString(App::Application::getHomePath());
path = home + path;
}
BitmapFactory().addPath(path);
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sAddIcon(PyObject * /*self*/, PyObject *args)
{
const char *iconName;
const char *content;
Py_ssize_t size = 0;
const char *format = "XPM";
if (!PyArg_ParseTuple(args, "ss#|s", &iconName,&content,&size,&format))
return NULL;
QPixmap icon;
if (BitmapFactory().findPixmapInCache(iconName, icon)) {
PyErr_SetString(PyExc_AssertionError, "Icon with this name already registered");
return NULL;
}
QByteArray ary(content,size);
icon.loadFromData(ary, format);
if (icon.isNull()){
QString file = QString::fromUtf8(content);
icon.load(file);
}
if (icon.isNull()) {
PyErr_SetString(Base::BaseExceptionFreeCADError, "Invalid icon added to application");
return NULL;
}
BitmapFactory().addPixmapToCache(iconName, icon);
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sGetIcon(PyObject * /*self*/, PyObject *args)
{
char *iconName;
if (!PyArg_ParseTuple(args, "s", &iconName))
return NULL;
PythonWrapper wrap;
wrap.loadGuiModule();
wrap.loadWidgetsModule();
auto pixmap = BitmapFactory().pixmap(iconName);
if(!pixmap.isNull())
return Py::new_reference_to(wrap.fromQIcon(new QIcon(pixmap)));
Py_Return;
}
PyObject* Application::sIsIconCached(PyObject * /*self*/, PyObject *args)
{
char *iconName;
if (!PyArg_ParseTuple(args, "s", &iconName))
return NULL;
QPixmap icon;
return Py::new_reference_to(Py::Boolean(BitmapFactory().findPixmapInCache(iconName, icon)));
}
PyObject* Application::sAddCommand(PyObject * /*self*/, PyObject *args)
{
char* pName;
char* pSource=0;
PyObject* pcCmdObj;
if (!PyArg_ParseTuple(args, "sO|s", &pName,&pcCmdObj,&pSource))
return NULL;
// get the call stack to find the Python module name
//
std::string module, group;
try {
Base::PyGILStateLocker lock;
Py::Module mod(PyImport_ImportModule("inspect"), true);
if (mod.isNull()) {
PyErr_SetString(PyExc_ImportError, "Cannot load inspect module");
return 0;
}
Py::Callable inspect(mod.getAttr("stack"));
Py::List list(inspect.apply());
std::string file;
// usually this is the file name of the calling script
Py::Object info = list.getItem(0);
PyObject *pyfile = PyStructSequence_GET_ITEM(*info,1);
if(!pyfile)
throw Py::Exception();
file = Py::Object(pyfile).as_string();
Base::FileInfo fi(file);
// convert backslashes to slashes
file = fi.filePath();
module = fi.fileNamePure();
// for the group name get the directory name after 'Mod'
boost::regex rx("/Mod/(\\w+)/");
boost::smatch what;
if (boost::regex_search(file, what, rx)) {
group = what[1];
}
else {
boost::regex rx("/Ext/freecad/(\\w+)/");
if (boost::regex_search(file, what, rx))
group = what[1];
else
group = module;
}
}
catch (Py::Exception& e) {
e.clear();
}
try {
Base::PyGILStateLocker lock;
Py::Object cmd(pcCmdObj);
if (cmd.hasAttr("GetCommands")) {
Command* cmd = new PythonGroupCommand(pName, pcCmdObj);
if (!module.empty()) {
cmd->setAppModuleName(module.c_str());
}
if (!group.empty()) {
cmd->setGroupName(group.c_str());
}
Application::Instance->commandManager().addCommand(cmd);
}
else {
Command* cmd = new PythonCommand(pName, pcCmdObj, pSource);
if (!module.empty()) {
cmd->setAppModuleName(module.c_str());
}
if (!group.empty()) {
cmd->setGroupName(group.c_str());
}
Application::Instance->commandManager().addCommand(cmd);
}
}
catch (const Base::Exception& e) {
PyErr_SetString(Base::BaseExceptionFreeCADError, e.what());
return 0;
}
catch (...) {
PyErr_SetString(Base::BaseExceptionFreeCADError, "Unknown C++ exception raised in Application::sAddCommand()");
return 0;
}
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sRunCommand(PyObject * /*self*/, PyObject *args)
{
char* pName;
int item = 0;
if (!PyArg_ParseTuple(args, "s|i", &pName, &item))
return NULL;
Gui::Command::LogDisabler d1;
Gui::SelectionLogDisabler d2;
Command* cmd = Application::Instance->commandManager().getCommandByName(pName);
if (cmd) {
cmd->invoke(item);
Py_INCREF(Py_None);
return Py_None;
}
else {
PyErr_Format(Base::BaseExceptionFreeCADError, "No such command '%s'", pName);
return 0;
}
}
PyObject* Application::sDoCommand(PyObject * /*self*/, PyObject *args)
{
char *sCmd=0;
if (!PyArg_ParseTuple(args, "s", &sCmd))
return NULL;
Gui::Command::LogDisabler d1;
Gui::SelectionLogDisabler d2;
Gui::Command::printPyCaller();
Gui::Application::Instance->macroManager()->addLine(MacroManager::App, sCmd);
PyObject *module, *dict;
Base::PyGILStateLocker locker;
module = PyImport_AddModule("__main__");
if (module == NULL)
return 0;
dict = PyModule_GetDict(module);
if (dict == NULL)
return 0;
return PyRun_String(sCmd, Py_file_input, dict, dict);
}
PyObject* Application::sDoCommandGui(PyObject * /*self*/, PyObject *args)
{
char *sCmd=0;
if (!PyArg_ParseTuple(args, "s", &sCmd))
return NULL;
Gui::Command::LogDisabler d1;
Gui::SelectionLogDisabler d2;
Gui::Command::printPyCaller();
Gui::Application::Instance->macroManager()->addLine(MacroManager::Gui, sCmd);
PyObject *module, *dict;
Base::PyGILStateLocker locker;
module = PyImport_AddModule("__main__");
if (module == NULL)
return 0;
dict = PyModule_GetDict(module);
if (dict == NULL)
return 0;
return PyRun_String(sCmd, Py_file_input, dict, dict);
}
PyObject* Application::sAddModule(PyObject * /*self*/, PyObject *args)
{
char *pstr=0;
if (!PyArg_ParseTuple(args, "s", &pstr))
return NULL;
try {
Command::addModule(Command::Doc,pstr);
Py_INCREF(Py_None);
return Py_None;
}
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
return 0;
}
}
PyObject* Application::sShowDownloads(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
Gui::Dialog::DownloadManager::getInstance();
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sShowPreferences(PyObject * /*self*/, PyObject *args)
{
char *pstr=0;
int idx=0;
if (!PyArg_ParseTuple(args, "|si", &pstr, &idx))
return NULL;
Gui::Dialog::DlgPreferencesImp cDlg(getMainWindow());
if (pstr)
cDlg.activateGroupPage(QString::fromUtf8(pstr),idx);
WaitCursor wc;
wc.restoreCursor();
cDlg.exec();
wc.setWaitCursor();
Py_INCREF(Py_None);
return Py_None;
}
PyObject* Application::sCreateViewer(PyObject * /*self*/, PyObject *args)
{
int num_of_views = 1;
char* title = nullptr;
// if one argument (int) is given
if (PyArg_ParseTuple(args, "|is", &num_of_views, &title))
{
if (num_of_views < 0)
return NULL;
else if (num_of_views==1)
{
View3DInventor* viewer = new View3DInventor(0, 0);
if (title)
viewer->setWindowTitle(QString::fromUtf8(title));
Gui::getMainWindow()->addWindow(viewer);
return viewer->getPyObject();
}
else
{
SplitView3DInventor* viewer = new SplitView3DInventor(num_of_views, 0, 0);
if (title)
viewer->setWindowTitle(QString::fromUtf8(title));
Gui::getMainWindow()->addWindow(viewer);
return viewer->getPyObject();
}
}
return Py_None;
}
PyObject* Application::sGetMarkerIndex(PyObject * /*self*/, PyObject *args)
{
char *pstr = 0;
int defSize = 9;
if (!PyArg_ParseTuple(args, "|si", &pstr, &defSize))
return NULL;
PY_TRY {
ParameterGrp::handle const hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
//find the appropriate marker style string token
std::string marker_arg = pstr;
std::list<std::pair<std::string, std::string> > markerList = {
{"square", "DIAMOND_FILLED"},
{"cross", "CROSS"},
{"plus", "PLUS"},
{"empty", "SQUARE_LINE"},
{"quad", "SQUARE_FILLED"},
{"circle", "CIRCLE_LINE"},
{"default", "CIRCLE_FILLED"}
};
std::list<std::pair<std::string, std::string>>::iterator markerStyle;
for (markerStyle = markerList.begin(); markerStyle != markerList.end(); ++markerStyle)
{
if (marker_arg == (*markerStyle).first || marker_arg == (*markerStyle).second)
break;
}
marker_arg = "CIRCLE_FILLED";
if (markerStyle != markerList.end())
marker_arg = (*markerStyle).second;
//get the marker size
int sizeList[]={5, 7, 9};
if (std::find(std::begin(sizeList), std::end(sizeList), defSize) == std::end(sizeList))
defSize = 9;
return Py_BuildValue("i", Gui::Inventor::MarkerBitmaps::getMarkerIndex(marker_arg, defSize));
}PY_CATCH;
}
PyObject* Application::sReload(PyObject * /*self*/, PyObject *args)
{
const char *name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
PY_TRY {
auto doc = Application::Instance->reopen(App::GetApplication().getDocument(name));
if(doc)
return doc->getPyObject();
}PY_CATCH;
Py_Return;
}
PyObject* Application::sLoadFile(PyObject * /*self*/, PyObject *args)
{
char *path, *mod="";
if (!PyArg_ParseTuple(args, "s|s", &path, &mod)) // convert args: Python->C
return 0; // NULL triggers exception
PY_TRY {
Base::FileInfo fi(path);
if (!fi.isFile() || !fi.exists()) {
PyErr_Format(PyExc_IOError, "File %s doesn't exist.", path);
return 0;
}
std::string module = mod;
if (module.empty()) {
std::string ext = fi.extension();
std::vector<std::string> modules = App::GetApplication().getImportModules(ext.c_str());
if (modules.empty()) {
PyErr_Format(PyExc_IOError, "Filetype %s is not supported.", ext.c_str());
return 0;
}
else {
module = modules.front();
}
}
Application::Instance->open(path,module.c_str());
Py_Return;
} PY_CATCH
}
PyObject* Application::sAddDocObserver(PyObject * /*self*/, PyObject *args)
{
PyObject* o;
if (!PyArg_ParseTuple(args, "O",&o))
return NULL;
PY_TRY {
DocumentObserverPython::addObserver(Py::Object(o));
Py_Return;
} PY_CATCH;
}
PyObject* Application::sRemoveDocObserver(PyObject * /*self*/, PyObject *args)
{
PyObject* o;
if (!PyArg_ParseTuple(args, "O",&o))
return NULL;
PY_TRY {
DocumentObserverPython::removeObserver(Py::Object(o));
Py_Return;
} PY_CATCH;
}
PyObject* Application::sCoinRemoveAllChildren(PyObject * /*self*/, PyObject *args)
{
PyObject *pynode;
if (!PyArg_ParseTuple(args, "O", &pynode))
return NULL;
PY_TRY {
void* ptr = 0;
Base::Interpreter().convertSWIGPointerObj("pivy.coin","_p_SoGroup", pynode, &ptr, 0);
coinRemoveAllChildren(reinterpret_cast<SoGroup*>(ptr));
Py_Return;
}PY_CATCH;
}
PyObject* Application::sListUserEditModes(PyObject * /*self*/, PyObject *args)
{
Py::List ret;
if (!PyArg_ParseTuple(args, ""))
return NULL;
for (auto const &uem : Instance->listUserEditModes()) {
ret.append(Py::String(uem.second));
}
return Py::new_reference_to(ret);
}
PyObject* Application::sGetUserEditMode(PyObject * /*self*/, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
return Py::new_reference_to(Py::String(Instance->getUserEditModeName()));
}
PyObject* Application::sSetUserEditMode(PyObject * /*self*/, PyObject *args)
{
char *mode = "";
if (!PyArg_ParseTuple(args, "s", &mode))
return NULL;
bool ok = Instance->setUserEditMode(std::string(mode));
return Py::new_reference_to(Py::Boolean(ok));
}