Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 734202bc81 | |||
| b7ab01e6de | |||
| 258f9f1577 | |||
| 783e1346c7 | |||
| 5fd5d40d8f | |||
| d13e777b28 | |||
| 9ae1297056 | |||
| 9f2401dd4e | |||
| 04641657d0 | |||
| 061439ee3b | |||
| 7479df7303 | |||
| e8bd919ff8 | |||
| 6f0d9c21f3 | |||
| 9c2cf7283b | |||
| 44f6e86d19 | |||
| 980bf9060e | |||
| f972b010bb | |||
| 5a1527f954 | |||
| dea7d2080b | |||
| a4a42b36e4 | |||
| 7fa0eea88a | |||
| 2b28c50525 | |||
| 31d9283325 | |||
| f07b6e3e17 | |||
| 38e0e99579 | |||
| 2483c467bb | |||
| d9b8faf8bf | |||
| 102b97aca7 | |||
| 1e9f9faa24 | |||
| 7320c4c448 | |||
| 3129ae4296 | |||
| 0572853dbd | |||
| 2f0c3a79fa | |||
| 0f29891a98 | |||
| 3eaf87b2dc | |||
| 60fd668d5c | |||
| 4351058504 | |||
| f2f4b44792 | |||
| 90ff921ef7 | |||
| 662aebd881 | |||
| d2f0c4f33d | |||
| b80d000aff | |||
| 627ae70a53 | |||
| a261a55adf | |||
| dbb4cc6415 | |||
| e25cd6c71b | |||
| 1fb7ed43cf | |||
| ebca0c9836 | |||
| 476b4d5f97 | |||
| 3450cf9860 | |||
| 0dc75267fe | |||
| f7dccfaa90 | |||
| 76542ae729 | |||
| 55698377f9 | |||
| f21cbce8cd | |||
| 9152703516 | |||
| c264c76d8f | |||
| d8f5560cac | |||
| 442e411cf0 | |||
| 55080952a8 | |||
| f185504b4e | |||
| 2bc3daedcc | |||
| 2cef63f8a3 | |||
| 81a7d937bd | |||
| 64f3424cab | |||
| 64cb745ddc | |||
| 228876f8f2 | |||
| 8ece48c70b |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Vendored
+2
-2
@@ -180,12 +180,12 @@ class R4: public R3
|
||||
{
|
||||
friend std::ostream& operator <<(std::ostream& f, const R4 & P )
|
||||
{ f << P.x << ' ' << P.y << ' ' << P.z << ' ' << P.omega; return f; }
|
||||
friend istream& operator >>(istream& f, R4 & P)
|
||||
friend std::istream& operator >>(std::istream& f, R4 & P)
|
||||
{ f >> P.x >> P.y >> P.z >> P.omega ; return f; }
|
||||
|
||||
friend std::ostream& operator <<(std::ostream& f, const R4 * P )
|
||||
{ f << P->x << ' ' << P->y << ' ' << P->z << ' ' << P->omega; return f; }
|
||||
friend istream& operator >>(istream& f, R4 * P)
|
||||
friend std::istream& operator >>(std::istream& f, R4 * P)
|
||||
{ f >> P->x >> P->y >> P->z >> P->omega ; return f; }
|
||||
|
||||
public:
|
||||
|
||||
@@ -1529,7 +1529,11 @@ void Application::initConfig(int argc, char ** argv)
|
||||
PyImport_AppendInittab ("FreeCAD", init_freecad_module);
|
||||
PyImport_AppendInittab ("__FreeCADBase__", init_freecad_base_module);
|
||||
#endif
|
||||
mConfig["PythonSearchPath"] = Interpreter().init(argc,argv);
|
||||
const char* pythonpath = Interpreter().init(argc,argv);
|
||||
if (pythonpath)
|
||||
mConfig["PythonSearchPath"] = pythonpath;
|
||||
else
|
||||
Base::Console().Warning("Encoding of Python paths failed\n");
|
||||
|
||||
// Parse the options that have impact on the init process
|
||||
ParseOptions(argc,argv);
|
||||
|
||||
@@ -3031,7 +3031,13 @@ void Document::breakDependency(DocumentObject* pcObject, bool clear)
|
||||
std::vector<App::ObjectIdentifier> paths;
|
||||
pcObject->ExpressionEngine.getPathsToDocumentObject(it->second, paths);
|
||||
for (std::vector<App::ObjectIdentifier>::iterator jt = paths.begin(); jt != paths.end(); ++jt) {
|
||||
pcObject->ExpressionEngine.setValue(*jt, nullptr);
|
||||
// When nullifying the expression handle case where an identifier lacks of the property
|
||||
try {
|
||||
pcObject->ExpressionEngine.setValue(*jt, nullptr);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
e.ReportException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,10 +496,27 @@ void DocumentObject::setDocument(App::Document* doc)
|
||||
onSettingDocument();
|
||||
}
|
||||
|
||||
void DocumentObject::onAboutToRemoveProperty(const char* prop)
|
||||
void DocumentObject::onAboutToRemoveProperty(const char* name)
|
||||
{
|
||||
if (_pDoc)
|
||||
_pDoc->removePropertyOfObject(this, prop);
|
||||
if (_pDoc) {
|
||||
_pDoc->removePropertyOfObject(this, name);
|
||||
|
||||
Property* prop = getDynamicPropertyByName(name);
|
||||
if (prop) {
|
||||
auto expressions = ExpressionEngine.getExpressions();
|
||||
std::vector<App::ObjectIdentifier> removeExpr;
|
||||
|
||||
for (auto it : expressions) {
|
||||
if (it.first.getProperty() == prop) {
|
||||
removeExpr.push_back(it.first);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it : removeExpr) {
|
||||
ExpressionEngine.setValue(it, boost::shared_ptr<Expression>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentObject::onBeforeChange(const Property* prop)
|
||||
|
||||
@@ -1062,6 +1062,7 @@ boost::any ObjectIdentifier::getValue() const
|
||||
|
||||
destructor d1(pyvalue);
|
||||
|
||||
Base::PyGILStateLocker locker;
|
||||
if (!pyvalue)
|
||||
throw Base::RuntimeError("Failed to get property value.");
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
@@ -1078,12 +1079,12 @@ boost::any ObjectIdentifier::getValue() const
|
||||
return boost::any(PyString_AsString(pyvalue));
|
||||
#endif
|
||||
else if (PyUnicode_Check(pyvalue)) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return boost::any(PyUnicode_AsUTF8(pyvalue));
|
||||
#else
|
||||
PyObject * s = PyUnicode_AsUTF8String(pyvalue);
|
||||
destructor d2(s);
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return boost::any(PyUnicode_AsUTF8(s));
|
||||
#else
|
||||
return boost::any(PyString_AsString(s));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -354,13 +354,15 @@ void InterpreterSingleton::runInteractiveString(const char *sCmd)
|
||||
PyErr_Fetch(&errobj, &errdata, &errtraceback);
|
||||
|
||||
RuntimeError exc(""); // do not use PyException since this clears the error indicator
|
||||
if (errdata) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
if (PyUnicode_Check(errdata))
|
||||
exc.setMessage(PyUnicode_AsUTF8(errdata));
|
||||
if (PyUnicode_Check(errdata))
|
||||
exc.setMessage(PyUnicode_AsUTF8(errdata));
|
||||
#else
|
||||
if (PyString_Check(errdata))
|
||||
exc.setMessage(PyString_AsString(errdata));
|
||||
if (PyString_Check(errdata))
|
||||
exc.setMessage(PyString_AsString(errdata));
|
||||
#endif
|
||||
}
|
||||
PyErr_Restore(errobj, errdata, errtraceback);
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
|
||||
@@ -2033,25 +2033,25 @@ namespace Py
|
||||
}
|
||||
|
||||
String()
|
||||
: SeqBase<Char>( PyUnicode_FromString( "" ) )
|
||||
: SeqBase<Char>( PyUnicode_FromString( "" ), true )
|
||||
{
|
||||
validate();
|
||||
}
|
||||
|
||||
String( const char *latin1 )
|
||||
: SeqBase<Char>( PyUnicode_FromString( latin1 ) )
|
||||
: SeqBase<Char>( PyUnicode_FromString( latin1 ), true )
|
||||
{
|
||||
validate();
|
||||
}
|
||||
|
||||
String( const std::string &latin1 )
|
||||
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1.c_str(), latin1.size() ) )
|
||||
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1.c_str(), latin1.size() ), true )
|
||||
{
|
||||
validate();
|
||||
}
|
||||
|
||||
String( const char *latin1, Py_ssize_t size )
|
||||
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1, size ) )
|
||||
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1, size ), true )
|
||||
{
|
||||
validate();
|
||||
}
|
||||
|
||||
@@ -571,20 +571,27 @@ QPixmap BitmapFactoryInst::merge(const QPixmap& p1, const QPixmap& p2, Position
|
||||
{
|
||||
// does the similar as the method above except that this method does not resize the resulting pixmap
|
||||
int x = 0, y = 0;
|
||||
#if QT_VERSION >= 0x050000
|
||||
qreal dpr1 = p1.devicePixelRatio();
|
||||
qreal dpr2 = p2.devicePixelRatio();
|
||||
#else
|
||||
qreal dpr1 = 1;
|
||||
qreal dpr2 = 1;
|
||||
#endif
|
||||
|
||||
switch (pos)
|
||||
{
|
||||
case TopLeft:
|
||||
break;
|
||||
case TopRight:
|
||||
x = p1.width () - p2.width ();
|
||||
x = p1.width ()/dpr1 - p2.width ()/dpr2;
|
||||
break;
|
||||
case BottomLeft:
|
||||
y = p1.height() - p2.height();
|
||||
y = p1.height()/dpr1 - p2.height()/dpr2;
|
||||
break;
|
||||
case BottomRight:
|
||||
x = p1.width () - p2.width ();
|
||||
y = p1.height() - p2.height();
|
||||
x = p1.width ()/dpr1 - p2.width ()/dpr2;
|
||||
y = p1.height()/dpr1 - p2.height()/dpr2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+24
-12
@@ -1092,9 +1092,15 @@ void StdCmdDelete::activated(int iMsg)
|
||||
// handle the view provider
|
||||
Gui::getMainWindow()->setUpdatesEnabled(false);
|
||||
|
||||
(*it)->openTransaction("Delete");
|
||||
vpedit->onDelete(ft->getSubNames());
|
||||
(*it)->commitTransaction();
|
||||
try {
|
||||
(*it)->openTransaction("Delete");
|
||||
vpedit->onDelete(ft->getSubNames());
|
||||
(*it)->commitTransaction();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
(*it)->abortTransaction();
|
||||
e.ReportException();
|
||||
}
|
||||
|
||||
Gui::getMainWindow()->setUpdatesEnabled(true);
|
||||
Gui::getMainWindow()->update();
|
||||
@@ -1171,18 +1177,24 @@ void StdCmdDelete::activated(int iMsg)
|
||||
|
||||
if (autoDeletion) {
|
||||
Gui::getMainWindow()->setUpdatesEnabled(false);
|
||||
(*it)->openTransaction("Delete");
|
||||
for (std::vector<Gui::SelectionObject>::iterator ft = sel.begin(); ft != sel.end(); ++ft) {
|
||||
Gui::ViewProvider* vp = pGuiDoc->getViewProvider(ft->getObject());
|
||||
if (vp) {
|
||||
// ask the ViewProvider if it wants to do some clean up
|
||||
if (vp->onDelete(ft->getSubNames())) {
|
||||
doCommand(Doc,"App.getDocument(\"%s\").removeObject(\"%s\")"
|
||||
,(*it)->getName(), ft->getFeatName());
|
||||
try {
|
||||
(*it)->openTransaction("Delete");
|
||||
for (std::vector<Gui::SelectionObject>::iterator ft = sel.begin(); ft != sel.end(); ++ft) {
|
||||
Gui::ViewProvider* vp = pGuiDoc->getViewProvider(ft->getObject());
|
||||
if (vp) {
|
||||
// ask the ViewProvider if it wants to do some clean up
|
||||
if (vp->onDelete(ft->getSubNames())) {
|
||||
doCommand(Doc,"App.getDocument(\"%s\").removeObject(\"%s\")"
|
||||
,(*it)->getName(), ft->getFeatName());
|
||||
}
|
||||
}
|
||||
}
|
||||
(*it)->commitTransaction();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
(*it)->abortTransaction();
|
||||
e.ReportException();
|
||||
}
|
||||
(*it)->commitTransaction();
|
||||
|
||||
Gui::getMainWindow()->setUpdatesEnabled(true);
|
||||
Gui::getMainWindow()->update();
|
||||
|
||||
@@ -199,6 +199,8 @@ QString FileDialog::getSaveFileName (QWidget * parent, const QString & caption,
|
||||
dlg.setDirectory(dirName);
|
||||
dlg.setOptions(options);
|
||||
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
||||
if (selectedFilter && !selectedFilter->isEmpty())
|
||||
dlg.selectNameFilter(*selectedFilter);
|
||||
dlg.onSelectedFilter(dlg.selectedNameFilter());
|
||||
dlg.setNameFilterDetailsVisible(true);
|
||||
dlg.setConfirmOverwrite(true);
|
||||
@@ -295,6 +297,8 @@ QString FileDialog::getOpenFileName(QWidget * parent, const QString & caption, c
|
||||
dlg.setOptions(options);
|
||||
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
||||
dlg.setNameFilterDetailsVisible(true);
|
||||
if (selectedFilter && !selectedFilter->isEmpty())
|
||||
dlg.selectNameFilter(*selectedFilter);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
if (selectedFilter)
|
||||
*selectedFilter = dlg.selectedNameFilter();
|
||||
@@ -369,6 +373,8 @@ QStringList FileDialog::getOpenFileNames (QWidget * parent, const QString & capt
|
||||
dlg.setOptions(options);
|
||||
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
||||
dlg.setNameFilterDetailsVisible(true);
|
||||
if (selectedFilter && !selectedFilter->isEmpty())
|
||||
dlg.selectNameFilter(*selectedFilter);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
if (selectedFilter)
|
||||
*selectedFilter = dlg.selectedNameFilter();
|
||||
|
||||
@@ -98,6 +98,12 @@ void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
|
||||
mainWindow = window;
|
||||
|
||||
#if defined(Q_OS_LINUX) && defined(SPNAV_FOUND)
|
||||
#if QT_VERSION >= 0x050200
|
||||
if (!QX11Info::isPlatformX11()) {
|
||||
Base::Console().Log("Application is not running on X11\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (spnav_x11_open(QX11Info::display(), window->winId()) == -1) {
|
||||
Base::Console().Log("Couldn't connect to spacenav daemon\n");
|
||||
} else {
|
||||
|
||||
@@ -390,7 +390,16 @@ int PolyPickerSelection::locationEvent(const SoLocation2Event* const, const QPoi
|
||||
|
||||
if (polyline.isWorking()) {
|
||||
// check the position
|
||||
#if QT_VERSION >= 0x050600
|
||||
qreal dpr = _pcView3D->getGLWidget()->devicePixelRatioF();
|
||||
#else
|
||||
qreal dpr = 1.0;
|
||||
#endif
|
||||
QRect r = _pcView3D->getGLWidget()->rect();
|
||||
if (dpr != 1.0) {
|
||||
r.setHeight(r.height()*dpr);
|
||||
r.setWidth(r.width()*dpr);
|
||||
}
|
||||
|
||||
if (!r.contains(clPoint)) {
|
||||
if (clPoint.x() < r.left())
|
||||
@@ -599,7 +608,16 @@ int FreehandSelection::locationEvent(const SoLocation2Event* const e, const QPoi
|
||||
|
||||
if (polyline.isWorking()) {
|
||||
// check the position
|
||||
#if QT_VERSION >= 0x050600
|
||||
qreal dpr = _pcView3D->getGLWidget()->devicePixelRatioF();
|
||||
#else
|
||||
qreal dpr = 1.0;
|
||||
#endif
|
||||
QRect r = _pcView3D->getGLWidget()->rect();
|
||||
if (dpr != 1.0) {
|
||||
r.setHeight(r.height()*dpr);
|
||||
r.setWidth(r.width()*dpr);
|
||||
}
|
||||
|
||||
if (!r.contains(clPoint)) {
|
||||
if (clPoint.x() < r.left())
|
||||
|
||||
@@ -116,7 +116,7 @@ QByteArray PythonOnlineHelp::loadResource(const QString& filename) const
|
||||
dict = PyDict_Copy(dict);
|
||||
|
||||
QByteArray cmd =
|
||||
"import string, os, sys, pydoc, pkgutil\n"
|
||||
"import os, sys, pydoc, pkgutil\n"
|
||||
"\n"
|
||||
"class FreeCADDoc(pydoc.HTMLDoc):\n"
|
||||
" def index(self, dir, shadowed=None):\n"
|
||||
@@ -160,7 +160,7 @@ QByteArray PythonOnlineHelp::loadResource(const QString& filename) const
|
||||
" ret = pydoc.html.index(dir, seen)\n"
|
||||
" if ret != None:\n"
|
||||
" indices.append(ret)\n"
|
||||
"contents = heading + string.join(indices) + '''<p align=right>\n"
|
||||
"contents = heading + ' '.join(indices) + '''<p align=right>\n"
|
||||
"<font color=\"#909090\" face=\"helvetica, arial\"><strong>\n"
|
||||
"pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'''\n"
|
||||
"htmldocument=pydoc.html.page(title,contents)\n";
|
||||
|
||||
@@ -323,7 +323,8 @@ void InteractiveInterpreter::runCode(PyCodeObject* code) const
|
||||
if (PyErr_Occurred()) { /* get latest python exception information */
|
||||
PyObject *errobj, *errdata, *errtraceback;
|
||||
PyErr_Fetch(&errobj, &errdata, &errtraceback);
|
||||
if (PyDict_Check(errdata)) {
|
||||
// the error message can be empty so errdata will be null
|
||||
if (errdata && PyDict_Check(errdata)) {
|
||||
PyObject* value = PyDict_GetItemString(errdata, "swhat");
|
||||
if (value) {
|
||||
Base::RuntimeError e;
|
||||
|
||||
@@ -477,7 +477,9 @@ void View3DInventor::printPreview()
|
||||
{
|
||||
QPrinter printer(QPrinter::ScreenResolution);
|
||||
printer.setFullPage(true);
|
||||
//printer.setPageSize(QPrinter::A3);
|
||||
#if (QT_VERSION > QT_VERSION_CHECK(5, 9, 0))
|
||||
printer.setPageSize(QPrinter::A4);
|
||||
#endif
|
||||
printer.setOrientation(QPrinter::Landscape);
|
||||
|
||||
QPrintPreviewDialog dlg(&printer, this);
|
||||
|
||||
+58
-19
@@ -232,6 +232,28 @@ Py::Object qt_wrapInstance(qttype object, const char* className,
|
||||
return func.apply(arguments);
|
||||
}
|
||||
|
||||
const char* qt_identifyType(QObject* ptr, const char* pyside)
|
||||
{
|
||||
PyObject* module = PyImport_ImportModule(pyside);
|
||||
if (!module) {
|
||||
std::string error = "Cannot load ";
|
||||
error += pyside;
|
||||
error += " module";
|
||||
throw Py::Exception(PyExc_ImportError, error);
|
||||
}
|
||||
|
||||
Py::Module qtmod(module);
|
||||
const QMetaObject* metaObject = ptr->metaObject();
|
||||
while (metaObject) {
|
||||
const char* className = metaObject->className();
|
||||
if (qtmod.getDict().hasKey(className))
|
||||
return className;
|
||||
metaObject = metaObject->superClass();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* qt_getCppPointer(const Py::Object& pyobject, const char* shiboken, const char* unwrap)
|
||||
{
|
||||
// https://github.com/PySide/Shiboken/blob/master/shibokenmodule/typesystem_shiboken.xml
|
||||
@@ -475,39 +497,50 @@ bool PythonWrapper::loadWidgetsModule()
|
||||
|
||||
void PythonWrapper::createChildrenNameAttributes(PyObject* root, QObject* object)
|
||||
{
|
||||
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
|
||||
Q_FOREACH (QObject* child, object->children()) {
|
||||
const QByteArray name = child->objectName().toLocal8Bit();
|
||||
|
||||
if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) {
|
||||
bool hasAttr = PyObject_HasAttrString(root, name.constData());
|
||||
if (!hasAttr) {
|
||||
#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2)
|
||||
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], child));
|
||||
#else
|
||||
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide_QtCoreTypes[SBK_QOBJECT_IDX], child));
|
||||
#endif
|
||||
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
|
||||
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython(reinterpret_cast<SbkObjectType*>(Shiboken::SbkType<QObject>()), child));
|
||||
PyObject_SetAttrString(root, name.constData(), pyChild);
|
||||
#elif QT_VERSION >= 0x050000
|
||||
const char* className = qt_identifyType(child, "PySide2.QtWidgets");
|
||||
if (!className) {
|
||||
if (qobject_cast<QWidget*>(child))
|
||||
className = "QWidget";
|
||||
else
|
||||
className = "QObject";
|
||||
}
|
||||
|
||||
Py::Object pyChild(qt_wrapInstance<QObject*>(child, className, "shiboken2", "PySide2.QtWidgets", "wrapInstance"));
|
||||
PyObject_SetAttrString(root, name.constData(), pyChild.ptr());
|
||||
#else
|
||||
const char* className = qt_identifyType(child, "PySide.QtGui");
|
||||
if (!className) {
|
||||
if (qobject_cast<QWidget*>(child))
|
||||
className = "QWidget";
|
||||
else
|
||||
className = "QObject";
|
||||
}
|
||||
|
||||
Py::Object pyChild(qt_wrapInstance<QObject*>(child, className, "shiboken", "PySide.QtGui", "wrapInstance"));
|
||||
PyObject_SetAttrString(root, name.constData(), pyChild.ptr());
|
||||
#endif
|
||||
}
|
||||
createChildrenNameAttributes(root, child);
|
||||
}
|
||||
createChildrenNameAttributes(root, child);
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(root);
|
||||
Q_UNUSED(object);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PythonWrapper::setParent(PyObject* pyWdg, QObject* parent)
|
||||
{
|
||||
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
|
||||
if (parent) {
|
||||
#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2)
|
||||
Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide2_QtGuiTypes[SBK_QWIDGET_IDX], parent));
|
||||
#else
|
||||
Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide_QtGuiTypes[SBK_QWIDGET_IDX], parent));
|
||||
#endif
|
||||
Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython(reinterpret_cast<SbkObjectType*>(Shiboken::SbkType<QWidget>()), parent));
|
||||
Shiboken::Object::setParent(pyParent, pyWdg);
|
||||
}
|
||||
#else
|
||||
@@ -680,7 +713,10 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
|
||||
str << "import pyside2uic\n"
|
||||
<< "from PySide2 import QtCore, QtGui, QtWidgets\n"
|
||||
<< "import xml.etree.ElementTree as xml\n"
|
||||
<< "from cStringIO import StringIO\n"
|
||||
<< "try:\n"
|
||||
<< " from cStringIO import StringIO\n"
|
||||
<< "except:\n"
|
||||
<< " from io import StringIO\n"
|
||||
<< "\n"
|
||||
<< "uiFile = \"" << file.c_str() << "\"\n"
|
||||
<< "parsed = xml.parse(uiFile)\n"
|
||||
@@ -691,7 +727,7 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
|
||||
<< " frame = {}\n"
|
||||
<< " pyside2uic.compileUi(f, o, indent=0)\n"
|
||||
<< " pyc = compile(o.getvalue(), '<string>', 'exec')\n"
|
||||
<< " exec pyc in frame\n"
|
||||
<< " exec(pyc, frame)\n"
|
||||
<< " #Fetch the base_class and form class based on their type in the xml from designer\n"
|
||||
<< " form_class = frame['Ui_%s'%form_class]\n"
|
||||
<< " base_class = eval('QtWidgets.%s'%widget_class)\n";
|
||||
@@ -699,7 +735,10 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
|
||||
str << "import pysideuic\n"
|
||||
<< "from PySide import QtCore, QtGui\n"
|
||||
<< "import xml.etree.ElementTree as xml\n"
|
||||
<< "from cStringIO import StringIO\n"
|
||||
<< "try:\n"
|
||||
<< " from cStringIO import StringIO\n"
|
||||
<< "except:\n"
|
||||
<< " from io import StringIO\n"
|
||||
<< "\n"
|
||||
<< "uiFile = \"" << file.c_str() << "\"\n"
|
||||
<< "parsed = xml.parse(uiFile)\n"
|
||||
@@ -710,7 +749,7 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
|
||||
<< " frame = {}\n"
|
||||
<< " pysideuic.compileUi(f, o, indent=0)\n"
|
||||
<< " pyc = compile(o.getvalue(), '<string>', 'exec')\n"
|
||||
<< " exec pyc in frame\n"
|
||||
<< " exec(pyc, frame)\n"
|
||||
<< " #Fetch the base_class and form class based on their type in the xml from designer\n"
|
||||
<< " form_class = frame['Ui_%s'%form_class]\n"
|
||||
<< " base_class = eval('QtGui.%s'%widget_class)\n";
|
||||
|
||||
@@ -298,7 +298,10 @@ class AddonsInstaller(QtGui.QDialog):
|
||||
if oktoclose:
|
||||
if hasattr(self,"install_worker"):
|
||||
QtGui.QMessageBox.information(self, translate("AddonsInstaller","Addon manager"), translate("AddonsInstaller","Please restart FreeCAD for changes to take effect."))
|
||||
shutil.rmtree(self.macro_repo_dir,onerror=self.remove_readonly)
|
||||
try:
|
||||
shutil.rmtree(self.macro_repo_dir,onerror=self.remove_readonly)
|
||||
except:
|
||||
FreeCAD.Console.PrintMessage(translate("AddonsInstaller", 'AddonManager - Macros, there was nothing to clean up'))
|
||||
QtGui.QDialog.reject(self)
|
||||
|
||||
def retranslateUi(self):
|
||||
@@ -568,23 +571,34 @@ class UpdateWorker(QtCore.QThread):
|
||||
p = p.decode("utf-8")
|
||||
u.close()
|
||||
p = p.replace("\n"," ")
|
||||
p = re.findall("octicon-file-submodule(.*?)message",p)
|
||||
#p = re.findall("octicon-file-submodule(.*?)<time-ago datetime",p)
|
||||
|
||||
# Fix for github oct 2020 changes. This is not needed anymore in 0.19
|
||||
# as this addon manager doesn't parse the html file anymore
|
||||
# the line below retreives a list of "Owner/Repo" strings
|
||||
p = ["/".join(e.split("/")[1:3]) for e in re.findall("href=\"(\/.*?tree.*?)\"",p) if not e.startswith("/FreeCAD/FreeCAD-addons")]
|
||||
basedir = FreeCAD.getUserAppDataDir()
|
||||
moddir = basedir + os.sep + "Mod"
|
||||
repos = []
|
||||
for l in p:
|
||||
#name = re.findall("data-skip-pjax=\"true\">(.*?)<",l)[0]
|
||||
name = re.findall("title=\"(.*?) @",l)[0]
|
||||
#name = re.findall("title=\"(.*?) @",l)[0]
|
||||
name = l.split("/")[1]
|
||||
self.info_label.emit(name)
|
||||
#url = re.findall("title=\"(.*?) @",l)[0]
|
||||
url = "https://github.com/" + re.findall("href=\"\/(.*?)\/tree",l)[0]
|
||||
addondir = moddir + os.sep + name
|
||||
#print ("found:",name," at ",url)
|
||||
if not os.path.exists(addondir):
|
||||
state = 0
|
||||
try:
|
||||
#url = "https://github.com/" + re.findall("href=\"\/(.*?)\/tree",l)[0]
|
||||
url = "https://github.com/" + l
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
state = 1
|
||||
repos.append([name,url,state])
|
||||
addondir = moddir + os.sep + name
|
||||
#print ("found:",name," at ",url)
|
||||
if not os.path.exists(addondir):
|
||||
state = 0
|
||||
else:
|
||||
state = 1
|
||||
repos.append([name,url,state])
|
||||
if not repos:
|
||||
self.info_label.emit(translate("AddonsInstaller", "Unable to download addon list."))
|
||||
else:
|
||||
@@ -715,16 +729,20 @@ class FillMacroListWorker(QtCore.QThread):
|
||||
return
|
||||
|
||||
self.info_label_signal.emit('Downloading list of macros for git...')
|
||||
git.Repo.clone_from('https://github.com/FreeCAD/FreeCAD-macros.git', self.repo_dir)
|
||||
for dirpath, _, filenames in os.walk(self.repo_dir):
|
||||
if '.git' in dirpath:
|
||||
continue
|
||||
for filename in filenames:
|
||||
if filename.lower().endswith('.fcmacro'):
|
||||
macro = Macro(filename[:-8]) # Remove ".FCMacro".
|
||||
macro.on_git = True
|
||||
macro.src_filename = os.path.join(dirpath, filename)
|
||||
self.macros.append(macro)
|
||||
try:
|
||||
git.Repo.clone_from('https://github.com/FreeCAD/FreeCAD-macros.git', self.repo_dir)
|
||||
for dirpath, _, filenames in os.walk(self.repo_dir):
|
||||
if '.git' in dirpath:
|
||||
continue
|
||||
for filename in filenames:
|
||||
if filename.lower().endswith('.fcmacro'):
|
||||
macro = Macro(filename[:-8]) # Remove ".FCMacro".
|
||||
macro.on_git = True
|
||||
macro.src_filename = os.path.join(dirpath, filename)
|
||||
self.macros.append(macro)
|
||||
except:
|
||||
FreeCAD.Console.PrintWarning(translate('AddonsInstaller', 'Something went wrong with the Git Macro Retieval, possibly the Git executable is not in the path')+"\n")
|
||||
|
||||
|
||||
def retrieve_macros_from_wiki(self):
|
||||
"""Retrieve macros from the wiki
|
||||
|
||||
@@ -250,6 +250,7 @@ class _ArchMaterial:
|
||||
"The Material object"
|
||||
|
||||
def __init__(self,obj):
|
||||
|
||||
self.Type = "Material"
|
||||
obj.Proxy = self
|
||||
obj.addProperty("App::PropertyString","Description","Arch",QT_TRANSLATE_NOOP("App::Property","A description for this material"))
|
||||
@@ -258,13 +259,23 @@ class _ArchMaterial:
|
||||
obj.addProperty("App::PropertyPercent","Transparency","Arch",QT_TRANSLATE_NOOP("App::Property","The transparency value of this material"))
|
||||
obj.addProperty("App::PropertyColor","Color","Arch",QT_TRANSLATE_NOOP("App::Property","The color of this material"))
|
||||
|
||||
def isSameColor(self,c1,c2):
|
||||
|
||||
r = 4
|
||||
if round(c1[0],r) == round(c2[0],r):
|
||||
if round(c1[1],r) == round(c2[1],r):
|
||||
if round(c1[2],r) == round(c2[2],r):
|
||||
return True
|
||||
return False
|
||||
|
||||
def onChanged(self,obj,prop):
|
||||
d = None
|
||||
|
||||
d = obj.Material
|
||||
if prop == "Material":
|
||||
if "DiffuseColor" in obj.Material:
|
||||
c = tuple([float(f) for f in obj.Material['DiffuseColor'].strip("()").split(",")])
|
||||
if hasattr(obj,"Color"):
|
||||
if obj.Color != c:
|
||||
if not self.isSameColor(obj.Color,c):
|
||||
obj.Color = c
|
||||
if "Transparency" in obj.Material:
|
||||
t = int(obj.Material['Transparency'])
|
||||
@@ -283,52 +294,50 @@ class _ArchMaterial:
|
||||
if hasattr(obj,"Description"):
|
||||
if obj.Description != obj.Material["Description"]:
|
||||
obj.Description = obj.Material["Description"]
|
||||
if "Name" in obj.Material:
|
||||
if hasattr(obj,"Label"):
|
||||
if obj.Label != obj.Material["Name"]:
|
||||
obj.Label = obj.Material["Name"]
|
||||
elif prop == "Label":
|
||||
if "Name" in d:
|
||||
if d["Name"] == obj.Label:
|
||||
return
|
||||
d["Name"] = obj.Label
|
||||
elif prop == "Color":
|
||||
if hasattr(obj,"Color"):
|
||||
if obj.Material:
|
||||
d = obj.Material
|
||||
val = str(obj.Color[:3])
|
||||
if "DiffuseColor" in d:
|
||||
if d["DiffuseColor"] == val:
|
||||
return
|
||||
d["DiffuseColor"] = val
|
||||
if "DiffuseColor" in d:
|
||||
if self.isSameColor(tuple([float(f) for f in d['DiffuseColor'].strip("()").split(",")]),obj.Color[:3]):
|
||||
return
|
||||
d["DiffuseColor"] = str(obj.Color[:3])
|
||||
elif prop == "Transparency":
|
||||
if hasattr(obj,"Transparency"):
|
||||
if obj.Material:
|
||||
d = obj.Material
|
||||
val = str(obj.Transparency)
|
||||
if "Transparency" in d:
|
||||
if d["Transparency"] == val:
|
||||
return
|
||||
d["Transparency"] = val
|
||||
val = str(obj.Transparency)
|
||||
if "Transparency" in d:
|
||||
if d["Transparency"] == val:
|
||||
return
|
||||
d["Transparency"] = val
|
||||
elif prop == "ProductURL":
|
||||
if hasattr(obj,"ProductURL"):
|
||||
if obj.Material:
|
||||
d = obj.Material
|
||||
val = obj.ProductURL
|
||||
if "ProductURL" in d:
|
||||
if d["ProductURL"] == val:
|
||||
return
|
||||
obj.Material["ProductURL"] = val
|
||||
val = obj.ProductURL
|
||||
if "ProductURL" in d:
|
||||
if d["ProductURL"] == val:
|
||||
return
|
||||
obj.Material["ProductURL"] = val
|
||||
elif prop == "StandardCode":
|
||||
if hasattr(obj,"StandardCode"):
|
||||
if obj.Material:
|
||||
d = obj.Material
|
||||
val = obj.StandardCode
|
||||
if "StandardCode" in d:
|
||||
if d["StandardCode"] == val:
|
||||
return
|
||||
d["StandardCode"] = val
|
||||
val = obj.StandardCode
|
||||
if "StandardCode" in d:
|
||||
if d["StandardCode"] == val:
|
||||
return
|
||||
d["StandardCode"] = val
|
||||
elif prop == "Description":
|
||||
if hasattr(obj,"Description"):
|
||||
if obj.Material:
|
||||
d = obj.Material
|
||||
val = obj.Description
|
||||
if "Description" in d:
|
||||
if d["Description"] == val:
|
||||
return
|
||||
d["Description"] = val
|
||||
if d:
|
||||
val = obj.Description
|
||||
if "Description" in d:
|
||||
if d["Description"] == val:
|
||||
return
|
||||
d["Description"] = val
|
||||
if d and (d != obj.Material):
|
||||
obj.Material = d
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
@@ -516,6 +525,11 @@ class _ArchMaterialTaskPanel:
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def reject(self):
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def chooseMat(self, card):
|
||||
"sets self.material from a card"
|
||||
if card in self.cards:
|
||||
|
||||
@@ -674,8 +674,12 @@ class _Roof(ArchComponent.Component):
|
||||
if obj.Base.Shape.Solids:
|
||||
return obj.Shape
|
||||
else :
|
||||
if self.sub:
|
||||
return self.sub
|
||||
if hasattr(self,"sub"):
|
||||
if self.sub:
|
||||
return self.sub
|
||||
else :
|
||||
self.execute(obj)
|
||||
return self.sub
|
||||
else :
|
||||
self.execute(obj)
|
||||
return self.sub
|
||||
|
||||
+17
-17
@@ -195,7 +195,7 @@ def export(exportList,filename):
|
||||
outfile.close()
|
||||
FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + " " + decode(filename) + "\n")
|
||||
if materials:
|
||||
outfile = pythonopen(filenamemtl,"wb")
|
||||
outfile = pythonopen(filenamemtl,"w")
|
||||
outfile.write("# FreeCAD v" + ver[0] + "." + ver[1] + " build" + ver[2] + " Arch module\n")
|
||||
outfile.write("# http://www.freecadweb.org\n")
|
||||
kinds = {"AmbientColor":"Ka ","DiffuseColor":"Kd ","SpecularColor":"Ks ","EmissiveColor":"Ke ","Transparency":"d "}
|
||||
@@ -219,23 +219,23 @@ def export(exportList,filename):
|
||||
FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + ' ' + decode(filenamemtl) + "\n")
|
||||
|
||||
|
||||
def decode(name):
|
||||
"decodes encoded strings"
|
||||
try:
|
||||
decodedName = (name.decode("utf8"))
|
||||
except UnicodeDecodeError:
|
||||
try:
|
||||
decodedName = (name.decode("latin1"))
|
||||
except UnicodeDecodeError:
|
||||
FreeCAD.Console.PrintError(translate("Arch","Error: Couldn't determine character encoding"))
|
||||
decodedName = name
|
||||
return decodedName
|
||||
#def decode(name):
|
||||
# "decodes encoded strings"
|
||||
# try:
|
||||
# decodedName = (name.decode("utf8"))
|
||||
# except UnicodeDecodeError:
|
||||
# try:
|
||||
# decodedName = (name.decode("latin1"))
|
||||
# except UnicodeDecodeError:
|
||||
# FreeCAD.Console.PrintError(translate("Arch","Error: Couldn't determine character encoding"))
|
||||
# decodedName = name
|
||||
# return decodedName
|
||||
|
||||
def open(filename):
|
||||
"called when freecad wants to open a file"
|
||||
docname = (os.path.splitext(os.path.basename(filename))[0]).encode("utf8")
|
||||
doc = FreeCAD.newDocument(docname)
|
||||
doc.Label = decode(docname)
|
||||
docname = (os.path.splitext(os.path.basename(filename))[0])
|
||||
doc = FreeCAD.newDocument(docname.encode("utf8"))
|
||||
doc.Label = docname
|
||||
return insert(filename,doc.Name)
|
||||
|
||||
def insert(filename,docname):
|
||||
@@ -246,7 +246,7 @@ def insert(filename,docname):
|
||||
doc = FreeCAD.newDocument(docname)
|
||||
FreeCAD.ActiveDocument = doc
|
||||
|
||||
with pythonopen(filename,"rb") as infile:
|
||||
with pythonopen(filename,"r") as infile:
|
||||
verts = []
|
||||
facets = []
|
||||
activeobject = None
|
||||
@@ -257,7 +257,7 @@ def insert(filename,docname):
|
||||
if line[:7] == "mtllib ":
|
||||
matlib = os.path.join(os.path.dirname(filename),line[7:])
|
||||
if os.path.exists(matlib):
|
||||
with pythonopen(matlib,"rb") as matfile:
|
||||
with pythonopen(matlib,"r") as matfile:
|
||||
mname = None
|
||||
color = None
|
||||
trans = None
|
||||
|
||||
@@ -87,22 +87,13 @@ def errorDXFLib(gui):
|
||||
if gui:
|
||||
from PySide import QtGui, QtCore
|
||||
from DraftTools import translate
|
||||
if float(FreeCAD.Version()[0]+"."+FreeCAD.Version()[1]) >= 0.17:
|
||||
message = translate("Draft","""Download of dxf libraries failed.
|
||||
message = translate("Draft","""Download of dxf libraries failed.
|
||||
Please install the dxf Library addon manually
|
||||
from menu Tools -> Addon Manager""")
|
||||
else:
|
||||
message = translate("Draft","""Download of dxf libraries failed.
|
||||
Please download and install them manually.
|
||||
See complete instructions at
|
||||
http://www.freecadweb.org/wiki/Dxf_Importer_Install""")
|
||||
QtGui.QMessageBox.information(None,"",message)
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning("The DXF import/export libraries needed by FreeCAD to handle the DXF format are not installed.\n")
|
||||
if float(FreeCAD.Version()[0]+"."+FreeCAD.Version()[1]) >= 0.17:
|
||||
FreeCAD.Console.PrintWarning("Please install the dxf Library addon from Tools -> Addons Manager\n")
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning("Please check https://github.com/yorikvanhavre/Draft-dxf-importer\n")
|
||||
FreeCAD.Console.PrintWarning("Please install the dxf Library addon from Tools -> Addons Manager\n")
|
||||
break
|
||||
progressbar.stop()
|
||||
sys.path.append(FreeCAD.ConfigGet("UserAppData"))
|
||||
@@ -110,17 +101,7 @@ http://www.freecadweb.org/wiki/Dxf_Importer_Install""")
|
||||
if gui:
|
||||
from PySide import QtGui, QtCore
|
||||
from DraftTools import translate
|
||||
if float(FreeCAD.Version()[0]+"."+FreeCAD.Version()[1]) >= 0.17:
|
||||
message = translate('draft',"""The DXF import/export libraries needed by FreeCAD to handle
|
||||
the DXF format were not found on this system.
|
||||
Please either enable FreeCAD to download these libraries:
|
||||
1 - Load Draft workbench
|
||||
2 - Menu Edit > Preferences > Import-Export > DXF > Enable downloads
|
||||
Or install the libraries manually by installing the dxf-Library addon
|
||||
from menu Tools -> Addon Manager.
|
||||
To enabled FreeCAD to download these libraries, answer Yes.""")
|
||||
else:
|
||||
message = translate('draft',"""The DXF import/export libraries needed by FreeCAD to handle
|
||||
message = translate('draft',"""The DXF import/export libraries needed by FreeCAD to handle
|
||||
the DXF format were not found on this system.
|
||||
Please either enable FreeCAD to download these libraries:
|
||||
1 - Load Draft workbench
|
||||
@@ -154,7 +135,10 @@ def getDXFlibs():
|
||||
global dxfLibrary,dxfColorMap,dxfReader
|
||||
import dxfLibrary
|
||||
import dxfColorMap
|
||||
import dxfReader
|
||||
try:
|
||||
import dxfReader
|
||||
except:
|
||||
libsok = False
|
||||
except ImportError:
|
||||
libsok = False
|
||||
FreeCAD.Console.PrintWarning("DXF libraries not found. Trying to download...\n")
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
using namespace Drawing;
|
||||
using namespace std;
|
||||
|
||||
TopoDS_Edge DrawingOutput::asCircle(const BRepAdaptor_Curve& c) const
|
||||
{
|
||||
|
||||
@@ -117,12 +117,15 @@ TaskFemConstraintTransform::TaskFemConstraintTransform(ViewProviderFemConstraint
|
||||
//Transformable surfaces
|
||||
Gui::Command::doCommand(Gui::Command::Doc,TaskFemConstraintTransform::getSurfaceReferences((static_cast<Fem::Constraint*>(ConstraintView->getObject()))->getNameInDocument()).c_str());
|
||||
std::vector<App::DocumentObject*> ObjDispl = pcConstraint->RefDispl.getValues();
|
||||
std::vector<App::DocumentObject*> nDispl = pcConstraint->NameDispl.getValues();
|
||||
std::vector<std::string> SubElemDispl = pcConstraint->RefDispl.getSubValues();
|
||||
|
||||
for (std::size_t i = 0; i < ObjDispl.size(); i++) {
|
||||
ui->lw_displobj_rect->addItem(makeRefText(ObjDispl[i], SubElemDispl[i]));
|
||||
ui->lw_displobj_cylin->addItem(makeRefText(ObjDispl[i], SubElemDispl[i]));
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> nDispl = pcConstraint->NameDispl.getValues();
|
||||
for (std::size_t i = 0; i < nDispl.size(); i++) {
|
||||
ui->lw_dis_rect->addItem(makeText(nDispl[i]));
|
||||
ui->lw_dis_cylin->addItem(makeText(nDispl[i]));
|
||||
}
|
||||
@@ -447,7 +450,7 @@ A = []\n\
|
||||
i = 0\n\
|
||||
ss = []\n\
|
||||
for member in members:\n\
|
||||
if (member.isDerivedFrom(\"Fem::ConstraintDisplacement\")) or (member.isDerivedFrom(\"Fem::ConstraintForce\")):\n\
|
||||
if ((member.isDerivedFrom(\"Fem::ConstraintDisplacement\")) or (member.isDerivedFrom(\"Fem::ConstraintForce\"))) and len(member.References) > 0:\n\
|
||||
m = member.References\n\
|
||||
A.append(m)\n\
|
||||
if i >0:\n\
|
||||
@@ -463,7 +466,10 @@ for member in members:\n\
|
||||
i = i+1\n\
|
||||
if i>0:\n\
|
||||
App.ActiveDocument."+showConstr+".RefDispl = [x]\n\
|
||||
App.ActiveDocument."+showConstr+".NameDispl = ss\n";
|
||||
App.ActiveDocument."+showConstr+".NameDispl = ss\n\
|
||||
else:\n\
|
||||
App.ActiveDocument."+showConstr+".RefDispl = None\n\
|
||||
App.ActiveDocument."+showConstr+".NameDispl = []\n";
|
||||
}
|
||||
|
||||
/* Note: */
|
||||
|
||||
@@ -29,6 +29,8 @@ __url__ = "http://www.freecadweb.org"
|
||||
# \ingroup FEM
|
||||
# \brief FreeCAD FEM FemSelectWidget
|
||||
|
||||
import sys
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import femmesh.meshtools as FemMeshTools
|
||||
@@ -160,10 +162,19 @@ class SolidSelector(_Selector):
|
||||
if solids:
|
||||
item = (selObj.Object, tuple(solids))
|
||||
selection.append(item)
|
||||
if len(selection) == 0:
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Object with no Shape selected or nothing selected at all.\n"
|
||||
)
|
||||
return selection
|
||||
|
||||
def _getObjects(self, obj, names):
|
||||
objects = []
|
||||
if not hasattr(obj, "Shape"):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Selected object has no Shape.\n"
|
||||
)
|
||||
return objects
|
||||
shape = obj.Shape
|
||||
for n in names:
|
||||
if n.startswith("Face"):
|
||||
@@ -195,7 +206,11 @@ class SolidSelector(_Selector):
|
||||
if(self._findSub(sub, solid.Vertexes)):
|
||||
foundSolids.add("Solid" + str(solidId + 1))
|
||||
if len(foundSolids) == 1:
|
||||
return iter(foundSolids).next()
|
||||
it = iter(foundSolids)
|
||||
if sys.version_info.major >= 3:
|
||||
return next(it)
|
||||
else:
|
||||
return it.next()
|
||||
return None
|
||||
|
||||
def _findSub(self, sub, subList):
|
||||
|
||||
@@ -295,14 +295,14 @@ def fill_femresult_mechanical(res_obj, result_set):
|
||||
if len(Peeq) > 0:
|
||||
if len(Peeq.values()) != len(disp.values()):
|
||||
Pe = []
|
||||
Pe_extra_nodes = Peeq.values()
|
||||
Pe_extra_nodes = list(Peeq.values())
|
||||
nodes = len(disp.values())
|
||||
for i in range(nodes):
|
||||
Pe_value = Pe_extra_nodes[i]
|
||||
Pe.append(Pe_value)
|
||||
res_obj.Peeq = Pe
|
||||
else:
|
||||
res_obj.Peeq = Peeq.values()
|
||||
res_obj.Peeq = list(Peeq.values())
|
||||
|
||||
# fill res_obj.Temperature if they exist
|
||||
# TODO, check if it is possible to have Temperature without disp, we would need to set NodeNumbers than
|
||||
@@ -311,7 +311,7 @@ def fill_femresult_mechanical(res_obj, result_set):
|
||||
if len(Temperature) > 0:
|
||||
if len(Temperature.values()) != len(disp.values()):
|
||||
Temp = []
|
||||
Temp_extra_nodes = Temperature.values()
|
||||
Temp_extra_nodes = list(Temperature.values())
|
||||
nodes = len(disp.values())
|
||||
for i in range(nodes):
|
||||
Temp_value = Temp_extra_nodes[i]
|
||||
|
||||
@@ -89,14 +89,13 @@ class _TaskPanel(object):
|
||||
self._part.ViewObject.show()
|
||||
|
||||
def reject(self):
|
||||
self._restoreVisibility()
|
||||
self._recomputeAndRestore()
|
||||
return True
|
||||
|
||||
def accept(self):
|
||||
if self._obj.References != self._refWidget.references():
|
||||
self._obj.References = self._refWidget.references()
|
||||
self._obj.Document.recompute()
|
||||
self._restoreVisibility()
|
||||
self._recomputeAndRestore()
|
||||
return True
|
||||
|
||||
def _restoreVisibility(self):
|
||||
@@ -110,4 +109,13 @@ class _TaskPanel(object):
|
||||
else:
|
||||
self._part.ViewObject.hide()
|
||||
|
||||
def _recomputeAndRestore(self):
|
||||
doc = Gui.getDocument(self._obj.Document)
|
||||
doc.Document.recompute()
|
||||
self._restoreVisibility()
|
||||
# TODO: test if there is an active selection observer
|
||||
# if yes Gui.Selection.removeObserver is your friend
|
||||
doc.resetEdit()
|
||||
|
||||
|
||||
## @}
|
||||
|
||||
@@ -28,6 +28,8 @@ __url__ = "http://www.freecadweb.org"
|
||||
|
||||
import subprocess
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
import femtools.femutils as femutils
|
||||
|
||||
from .. import run
|
||||
@@ -112,7 +114,10 @@ class Solve(run.Solve):
|
||||
def _updateOutput(self, output):
|
||||
if self.solver.ElmerOutput is None:
|
||||
self._createOutput()
|
||||
self.solver.ElmerOutput.Text = output.decode("utf-8")
|
||||
if sys.version_info.major >= 3:
|
||||
self.solver.ElmerOutput.Text = output
|
||||
else:
|
||||
self.solver.ElmerOutput.Text = output.decode("utf-8")
|
||||
|
||||
def _createOutput(self):
|
||||
self.solver.ElmerOutput = self.analysis.Document.addObject(
|
||||
|
||||
@@ -536,11 +536,11 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject):
|
||||
ccx_path = FreeCAD.getHomePath() + "bin/ccx.exe"
|
||||
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx").SetString("ccxBinaryPath", ccx_path)
|
||||
self.ccx_binary = ccx_path
|
||||
elif system() == "Linux":
|
||||
elif system() in ("Linux", "Darwin"):
|
||||
p1 = subprocess.Popen(['which', 'ccx'], stdout=subprocess.PIPE)
|
||||
if p1.wait() == 0:
|
||||
if sys.version_info.major >= 3:
|
||||
ccx_path = str(p1.stdout.read()).split('\n')[0]
|
||||
ccx_path = p1.stdout.read().decode("utf8").split('\n')[0]
|
||||
else:
|
||||
ccx_path = p1.stdout.read().split('\n')[0]
|
||||
elif p1.wait() == 1:
|
||||
|
||||
+5
-3
@@ -22,11 +22,15 @@
|
||||
#* Milos Koutny 2010 *
|
||||
#***************************************************************************/
|
||||
|
||||
import FreeCAD, Part, os, FreeCADGui, __builtin__
|
||||
import FreeCAD, Part, os, FreeCADGui
|
||||
from FreeCAD import Base
|
||||
from math import *
|
||||
import ImportGui
|
||||
|
||||
# to distinguish python built-in open function from the one declared here
|
||||
if open.__module__ in ['__builtin__','io']:
|
||||
pythonopen = open
|
||||
|
||||
##########################################################
|
||||
# Script version dated 19-Jan-2012 #
|
||||
##########################################################
|
||||
@@ -54,8 +58,6 @@ IDF_diag_path="/tmp" # path for output of footprint.lst and missing_models.lst
|
||||
# End config section do not touch code below #
|
||||
########################################################################################
|
||||
|
||||
pythonopen = __builtin__.open # to distinguish python built-in open function from the one declared here
|
||||
|
||||
def open(filename):
|
||||
"""called when freecad opens an Emn file"""
|
||||
docname = os.path.splitext(os.path.basename(filename))[0]
|
||||
|
||||
@@ -138,8 +138,15 @@ def cmdCreateImageScaling(name):
|
||||
def accept(self):
|
||||
sel = FreeCADGui.Selection.getSelection()
|
||||
try:
|
||||
locale=QtCore.QLocale.system()
|
||||
d, ok = locale.toFloat(str(eval(self.lineEdit.text())))
|
||||
try:
|
||||
q = FreeCAD.Units.parseQuantity(self.lineEdit.text())
|
||||
d = q.Value
|
||||
if q.Unit == FreeCAD.Units.Unit(): # plain number
|
||||
ok = True
|
||||
elif q.Unit == FreeCAD.Units.Length:
|
||||
ok = True
|
||||
except:
|
||||
ok = False
|
||||
if not ok:
|
||||
raise ValueError
|
||||
s=d/self.distance
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import sys
|
||||
|
||||
# here the usage description if you use this tool from the command line ("__main__")
|
||||
CommandlineUsage = """Material - Tool to work with FreeCAD Material definition cards
|
||||
|
||||
@@ -62,7 +64,10 @@ def importFCMat(fileName):
|
||||
|
||||
Config = configparser.RawConfigParser()
|
||||
Config.optionxform = str
|
||||
Config.read(fileName)
|
||||
if sys.version_info.major >= 3:
|
||||
Config.read(fileName, encoding='utf-8') # respect unicode filenames
|
||||
else:
|
||||
Config.read(fileName)
|
||||
dict1 = {}
|
||||
for section in Config.sections():
|
||||
options = Config.options(section)
|
||||
|
||||
@@ -42,6 +42,8 @@ except AttributeError:
|
||||
return QtGui.QApplication.translate(context, text, None)
|
||||
|
||||
import io
|
||||
import sys
|
||||
PY2 = sys.version_info.major == 2
|
||||
|
||||
try:
|
||||
import FreeCAD
|
||||
@@ -144,18 +146,23 @@ def callopenscad(inputfilename,outputfilename=None,outputext='csg',keepname=Fals
|
||||
import FreeCAD,os,subprocess,tempfile,time
|
||||
def check_output2(*args,**kwargs):
|
||||
kwargs.update({'stdout':subprocess.PIPE,'stderr':subprocess.PIPE})
|
||||
p=subprocess.Popen(*args,**kwargs)
|
||||
if PY2:
|
||||
p=subprocess.Popen(*args)
|
||||
else:
|
||||
p=subprocess.Popen(*args,**kwargs)
|
||||
stdoutd,stderrd = p.communicate()
|
||||
stdoutd = stdoutd.decode("utf8")
|
||||
stderrd = stderrd.decode("utf8")
|
||||
if not PY2:
|
||||
stdoutd = stdoutd.decode("utf8")
|
||||
stderrd = stderrd.decode("utf8")
|
||||
if p.returncode != 0:
|
||||
raise OpenSCADError('%s %s\n' % (stdoutd.strip(),stderrd.strip()))
|
||||
#raise Exception,'stdout %s\n stderr%s' %(stdoutd,stderrd)
|
||||
if stderrd.strip():
|
||||
FreeCAD.Console.PrintWarning(stderrd+u'\n')
|
||||
if stdoutd.strip():
|
||||
FreeCAD.Console.PrintMessage(stdoutd+u'\n')
|
||||
return stdoutd
|
||||
if not PY2:
|
||||
if stderrd.strip():
|
||||
FreeCAD.Console.PrintWarning(stderrd+u'\n')
|
||||
if stdoutd.strip():
|
||||
FreeCAD.Console.PrintMessage(stdoutd+u'\n')
|
||||
return stdoutd
|
||||
|
||||
osfilename = FreeCAD.ParamGet(\
|
||||
"User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
|
||||
@@ -182,7 +189,10 @@ def callopenscadstring(scadstr,outputext='csg'):
|
||||
dir1=tempfile.gettempdir()
|
||||
inputfilename=os.path.join(dir1,'%s.scad' % next(tempfilenamegen))
|
||||
inputfile = io.open(inputfilename,'w', encoding="utf8")
|
||||
inputfile.write(scadstr)
|
||||
if PY2:
|
||||
inputfile.write(scadstr.decode('utf8'))
|
||||
else:
|
||||
inputfile.write(scadstr)
|
||||
inputfile.close()
|
||||
outputfilename = callopenscad(inputfilename,outputext=outputext,\
|
||||
keepname=True)
|
||||
|
||||
@@ -66,21 +66,29 @@ App::DocumentObjectExecReturn *Compound::execute(void)
|
||||
TopoDS_Compound comp;
|
||||
builder.MakeCompound(comp);
|
||||
|
||||
// avoid duplicates without changing the order
|
||||
// See also ViewProviderCompound::updateData
|
||||
std::set<DocumentObject*> tempLinks;
|
||||
|
||||
const std::vector<DocumentObject*>& links = Links.getValues();
|
||||
for (std::vector<DocumentObject*>::const_iterator it = links.begin(); it != links.end(); ++it) {
|
||||
if (*it && (*it)->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
Part::Feature* fea = static_cast<Part::Feature*>(*it);
|
||||
const TopoDS_Shape& sh = fea->Shape.getValue();
|
||||
if (!sh.IsNull()) {
|
||||
builder.Add(comp, sh);
|
||||
TopTools_IndexedMapOfShape faceMap;
|
||||
TopExp::MapShapes(sh, TopAbs_FACE, faceMap);
|
||||
ShapeHistory hist;
|
||||
hist.type = TopAbs_FACE;
|
||||
for (int i=1; i<=faceMap.Extent(); i++) {
|
||||
hist.shapeMap[i-1].push_back(countFaces++);
|
||||
|
||||
auto pos = tempLinks.insert(fea);
|
||||
if (pos.second) {
|
||||
const TopoDS_Shape& sh = fea->Shape.getValue();
|
||||
if (!sh.IsNull()) {
|
||||
builder.Add(comp, sh);
|
||||
TopTools_IndexedMapOfShape faceMap;
|
||||
TopExp::MapShapes(sh, TopAbs_FACE, faceMap);
|
||||
ShapeHistory hist;
|
||||
hist.type = TopAbs_FACE;
|
||||
for (int i=1; i<=faceMap.Extent(); i++) {
|
||||
hist.shapeMap[i-1].push_back(countFaces++);
|
||||
}
|
||||
history.push_back(hist);
|
||||
}
|
||||
history.push_back(hist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ unsigned int Geometry::getMemSize (void) const
|
||||
void Geometry::Save(Base::Writer &writer) const
|
||||
{
|
||||
const char c = Construction?'1':'0';
|
||||
writer.Stream() << writer.ind() << "<Construction value=\"" << c << "\"/>" << endl;
|
||||
writer.Stream() << writer.ind() << "<Construction value=\"" << c << "\"/>" << std::endl;
|
||||
}
|
||||
|
||||
void Geometry::Restore(Base::XMLReader &reader)
|
||||
@@ -323,7 +323,7 @@ void GeomPoint::Save(Base::Writer &writer) const
|
||||
<< "X=\"" << Point.x <<
|
||||
"\" Y=\"" << Point.y <<
|
||||
"\" Z=\"" << Point.z <<
|
||||
"\"/>" << endl;
|
||||
"\"/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomPoint::Restore(Base::XMLReader &reader)
|
||||
@@ -793,7 +793,7 @@ void GeomBezierCurve::Save(Base::Writer& writer) const
|
||||
<< writer.ind()
|
||||
<< "<BezierCurve "
|
||||
<< "PolesCount=\"" << poles.size() <<
|
||||
"\">" << endl;
|
||||
"\">" << std::endl;
|
||||
|
||||
writer.incInd();
|
||||
|
||||
@@ -808,11 +808,11 @@ void GeomBezierCurve::Save(Base::Writer& writer) const
|
||||
"\" Y=\"" << (*itp).y <<
|
||||
"\" Z=\"" << (*itp).z <<
|
||||
"\" Weight=\"" << (*itw) <<
|
||||
"\"/>" << endl;
|
||||
"\"/>" << std::endl;
|
||||
}
|
||||
|
||||
writer.decInd();
|
||||
writer.Stream() << writer.ind() << "</BezierCurve>" << endl ;
|
||||
writer.Stream() << writer.ind() << "</BezierCurve>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomBezierCurve::Restore(Base::XMLReader& reader)
|
||||
@@ -1270,7 +1270,7 @@ void GeomBSplineCurve::Save(Base::Writer& writer) const
|
||||
"\" KnotsCount=\"" << knots.size() <<
|
||||
"\" Degree=\"" << degree <<
|
||||
"\" IsPeriodic=\"" << (int) isperiodic <<
|
||||
"\">" << endl;
|
||||
"\">" << std::endl;
|
||||
|
||||
writer.incInd();
|
||||
|
||||
@@ -1285,7 +1285,7 @@ void GeomBSplineCurve::Save(Base::Writer& writer) const
|
||||
"\" Y=\"" << (*itp).y <<
|
||||
"\" Z=\"" << (*itp).z <<
|
||||
"\" Weight=\"" << (*itw) <<
|
||||
"\"/>" << endl;
|
||||
"\"/>" << std::endl;
|
||||
}
|
||||
|
||||
std::vector<double>::const_iterator itk;
|
||||
@@ -1297,11 +1297,11 @@ void GeomBSplineCurve::Save(Base::Writer& writer) const
|
||||
<< "<Knot "
|
||||
<< "Value=\"" << (*itk)
|
||||
<< "\" Mult=\"" << (*itm) <<
|
||||
"\"/>" << endl;
|
||||
"\"/>" << std::endl;
|
||||
}
|
||||
|
||||
writer.decInd();
|
||||
writer.Stream() << writer.ind() << "</BSplineCurve>" << endl ;
|
||||
writer.Stream() << writer.ind() << "</BSplineCurve>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomBSplineCurve::Restore(Base::XMLReader& reader)
|
||||
@@ -1903,7 +1903,7 @@ void GeomCircle::Save(Base::Writer& writer) const
|
||||
"\" NormalZ=\"" << normal.Z() <<
|
||||
"\" AngleXU=\"" << AngleXU <<
|
||||
"\" Radius=\"" << this->myCurve->Radius() <<
|
||||
"\"/>" << endl;
|
||||
"\"/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomCircle::Restore(Base::XMLReader& reader)
|
||||
@@ -2132,7 +2132,7 @@ void GeomArcOfCircle::Save(Base::Writer &writer) const
|
||||
"\" Radius=\"" << circle->Radius() <<
|
||||
"\" StartAngle=\"" << this->myCurve->FirstParameter() <<
|
||||
"\" EndAngle=\"" << this->myCurve->LastParameter() <<
|
||||
"\"/>" << endl;
|
||||
"\"/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomArcOfCircle::Restore(Base::XMLReader &reader)
|
||||
@@ -2383,7 +2383,7 @@ void GeomEllipse::Save(Base::Writer& writer) const
|
||||
<< "MajorRadius=\"" << this->myCurve->MajorRadius() << "\" "
|
||||
<< "MinorRadius=\"" << this->myCurve->MinorRadius() << "\" "
|
||||
<< "AngleXU=\"" << AngleXU << "\" "
|
||||
<< "/>" << endl;
|
||||
<< "/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomEllipse::Restore(Base::XMLReader& reader)
|
||||
@@ -2653,7 +2653,7 @@ void GeomArcOfEllipse::Save(Base::Writer &writer) const
|
||||
<< "AngleXU=\"" << AngleXU << "\" "
|
||||
<< "StartAngle=\"" << this->myCurve->FirstParameter() << "\" "
|
||||
<< "EndAngle=\"" << this->myCurve->LastParameter() << "\" "
|
||||
<< "/>" << endl;
|
||||
<< "/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomArcOfEllipse::Restore(Base::XMLReader &reader)
|
||||
@@ -2826,7 +2826,7 @@ void GeomHyperbola::Save(Base::Writer& writer) const
|
||||
<< "MajorRadius=\"" << this->myCurve->MajorRadius() << "\" "
|
||||
<< "MinorRadius=\"" << this->myCurve->MinorRadius() << "\" "
|
||||
<< "AngleXU=\"" << AngleXU << "\" "
|
||||
<< "/>" << endl;
|
||||
<< "/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomHyperbola::Restore(Base::XMLReader& reader)
|
||||
@@ -3083,7 +3083,7 @@ void GeomArcOfHyperbola::Save(Base::Writer &writer) const
|
||||
<< "AngleXU=\"" << AngleXU << "\" "
|
||||
<< "StartAngle=\"" << this->myCurve->FirstParameter() << "\" "
|
||||
<< "EndAngle=\"" << this->myCurve->LastParameter() << "\" "
|
||||
<< "/>" << endl;
|
||||
<< "/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomArcOfHyperbola::Restore(Base::XMLReader &reader)
|
||||
@@ -3236,7 +3236,7 @@ void GeomParabola::Save(Base::Writer& writer) const
|
||||
<< "NormalZ=\"" << normal.Z() << "\" "
|
||||
<< "Focal=\"" << this->myCurve->Focal() << "\" "
|
||||
<< "AngleXU=\"" << AngleXU << "\" "
|
||||
<< "/>" << endl;
|
||||
<< "/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomParabola::Restore(Base::XMLReader& reader)
|
||||
@@ -3436,7 +3436,7 @@ void GeomArcOfParabola::Save(Base::Writer &writer) const
|
||||
<< "AngleXU=\"" << AngleXU << "\" "
|
||||
<< "StartAngle=\"" << this->myCurve->FirstParameter() << "\" "
|
||||
<< "EndAngle=\"" << this->myCurve->LastParameter() << "\" "
|
||||
<< "/>" << endl;
|
||||
<< "/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomArcOfParabola::Restore(Base::XMLReader &reader)
|
||||
@@ -3581,7 +3581,7 @@ void GeomLine::Save(Base::Writer &writer) const
|
||||
"\" DirX=\"" << Dir.x <<
|
||||
"\" DirY=\"" << Dir.y <<
|
||||
"\" DirZ=\"" << Dir.z <<
|
||||
"\"/>" << endl;
|
||||
"\"/>" << std::endl;
|
||||
}
|
||||
void GeomLine::Restore(Base::XMLReader &reader)
|
||||
{
|
||||
@@ -3722,7 +3722,7 @@ void GeomLineSegment::Save (Base::Writer &writer) const
|
||||
"\" EndX=\"" << End.x <<
|
||||
"\" EndY=\"" << End.y <<
|
||||
"\" EndZ=\"" << End.z <<
|
||||
"\"/>" << endl;
|
||||
"\"/>" << std::endl;
|
||||
}
|
||||
|
||||
void GeomLineSegment::Restore (Base::XMLReader &reader)
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
#include <Mod/Part/App/Geom2d/OffsetCurve2dPy.h>
|
||||
|
||||
using namespace Part;
|
||||
using namespace std;
|
||||
|
||||
extern const char* gce_ErrorStatusText(gce_ErrorType et);
|
||||
|
||||
|
||||
@@ -281,11 +281,11 @@ static void BRepTools_Write(const TopoDS_Shape& Sh, Standard_OStream& S) {
|
||||
static Standard_Boolean BRepTools_Write(const TopoDS_Shape& Sh,
|
||||
const Standard_CString File)
|
||||
{
|
||||
ofstream os;
|
||||
std::ofstream os;
|
||||
#if OCC_VERSION_HEX >= 0x060800
|
||||
OSD_OpenStream(os, File, ios::out);
|
||||
OSD_OpenStream(os, File, std::ios::out);
|
||||
#else
|
||||
os.open(File, ios::out);
|
||||
os.open(File, std::ios::out);
|
||||
#endif
|
||||
if (!os.rdbuf()->is_open()) return Standard_False;
|
||||
|
||||
|
||||
@@ -3084,8 +3084,14 @@ void TopoShape::getDomains(std::vector<Domain>& domains) const
|
||||
|
||||
TopLoc_Location loc;
|
||||
Handle(Poly_Triangulation) theTriangulation = BRep_Tool::Triangulation(face, loc);
|
||||
if (theTriangulation.IsNull())
|
||||
if (theTriangulation.IsNull()) {
|
||||
// For a face that cannot be meshed append an empty domain.
|
||||
// It's important for some algorithms (e.g. color mapping) that the numbers of
|
||||
// faces and domains match
|
||||
Domain domain;
|
||||
domains.push_back(domain);
|
||||
continue;
|
||||
}
|
||||
|
||||
Domain domain;
|
||||
// copy the points
|
||||
|
||||
@@ -908,11 +908,15 @@ void CmdPartCompound::activated(int iMsg)
|
||||
|
||||
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
|
||||
std::stringstream str;
|
||||
std::vector<std::string> tempSelNames;
|
||||
|
||||
// avoid duplicates without changing the order
|
||||
std::set<std::string> tempSelNames;
|
||||
str << "App.activeDocument()." << FeatName << ".Links = [";
|
||||
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
|
||||
str << "App.activeDocument()." << it->FeatName << ",";
|
||||
tempSelNames.push_back(it->FeatName);
|
||||
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it) {
|
||||
auto pos = tempSelNames.insert(it->FeatName);
|
||||
if (pos.second) {
|
||||
str << "App.activeDocument()." << it->FeatName << ",";
|
||||
}
|
||||
}
|
||||
str << "]";
|
||||
|
||||
|
||||
@@ -383,8 +383,8 @@ void PartGui::DimensionLinear::setupDimension()
|
||||
|
||||
//dimension arrows
|
||||
float dimLength = (point2.getValue()-point1.getValue()).length();
|
||||
float coneHeight = dimLength * .05;
|
||||
float coneRadius = coneHeight / 2;
|
||||
float coneHeight = dimLength * 0.05;
|
||||
float coneRadius = coneHeight * 0.5;
|
||||
|
||||
SoCone *cone = new SoCone();
|
||||
cone->bottomRadius.setValue(coneRadius);
|
||||
@@ -392,8 +392,8 @@ void PartGui::DimensionLinear::setupDimension()
|
||||
|
||||
char lStr[100];
|
||||
char rStr[100];
|
||||
snprintf(lStr, sizeof(lStr), "translation %.2f 0.0 0.0", coneHeight*0.5);
|
||||
snprintf(rStr, sizeof(rStr), "translation 0.0 -%.2f 0.0", coneHeight*0.5);
|
||||
snprintf(lStr, sizeof(lStr), "translation %.6f 0.0 0.0", coneHeight * 0.5);
|
||||
snprintf(rStr, sizeof(rStr), "translation 0.0 -%.6f 0.0", coneHeight * 0.5);
|
||||
|
||||
setPart("leftArrow.shape", cone);
|
||||
set("leftArrow.transform", "rotation 0.0 0.0 1.0 1.5707963");
|
||||
@@ -1072,7 +1072,7 @@ void PartGui::DimensionAngular::setupDimension()
|
||||
|
||||
//dimension arrows
|
||||
float coneHeight = radius.getValue() * 0.1;
|
||||
float coneRadius = coneHeight / 2;
|
||||
float coneRadius = coneHeight * 0.5;
|
||||
|
||||
SoCone *cone = new SoCone();
|
||||
cone->bottomRadius.setValue(coneRadius);
|
||||
@@ -1080,8 +1080,8 @@ void PartGui::DimensionAngular::setupDimension()
|
||||
|
||||
char str1[100];
|
||||
char str2[100];
|
||||
snprintf(str1, sizeof(str1), "translation 0.0 %.2f 0.0", coneHeight*0.5);
|
||||
snprintf(str2, sizeof(str2), "translation 0.0 -%.2f 0.0", coneHeight*0.5);
|
||||
snprintf(str1, sizeof(str1), "translation 0.0 %.6f 0.0", coneHeight * 0.5);
|
||||
snprintf(str2, sizeof(str2), "translation 0.0 -%.6f 0.0", coneHeight * 0.5);
|
||||
|
||||
setPart("arrow1.shape", cone);
|
||||
set("arrow1.localTransform", "rotation 0.0 0.0 1.0 3.1415927");
|
||||
|
||||
@@ -72,6 +72,24 @@ void ViewProviderCompound::updateData(const App::Property* prop)
|
||||
(prop)->getValues();
|
||||
Part::Compound* objComp = static_cast<Part::Compound*>(getObject());
|
||||
std::vector<App::DocumentObject*> sources = objComp->Links.getValues();
|
||||
|
||||
if (hist.size() != sources.size()) {
|
||||
// avoid duplicates without changing the order
|
||||
// See also Compound::execute
|
||||
std::set<App::DocumentObject*> tempSources;
|
||||
std::vector<App::DocumentObject*> filter;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = sources.begin(); it != sources.end(); ++it) {
|
||||
Part::Feature* objBase = dynamic_cast<Part::Feature*>(*it);
|
||||
if (objBase) {
|
||||
auto pos = tempSources.insert(objBase);
|
||||
if (pos.second) {
|
||||
filter.push_back(objBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sources = filter;
|
||||
}
|
||||
if (hist.size() != sources.size())
|
||||
return;
|
||||
|
||||
|
||||
@@ -643,9 +643,11 @@ void CmdPartDesignDuplicateSelection::activated(int iMsg)
|
||||
|
||||
std::vector<App::DocumentObject*> beforeFeatures = getDocument()->getObjects();
|
||||
|
||||
openCommand("Duplicate a PartDesign object");
|
||||
doCommand(Doc,"FreeCADGui.runCommand('Std_DuplicateSelection')");
|
||||
|
||||
// This transaction must be opened after using the core duplication function.
|
||||
// See https://forum.freecadweb.org/viewtopic.php?f=19&t=41918&p=355939#p355939
|
||||
openCommand("Duplicate a PartDesign object");
|
||||
if (pcActiveBody) {
|
||||
// Find the features that were added
|
||||
std::vector<App::DocumentObject*> afterFeatures = getDocument()->getObjects();
|
||||
|
||||
@@ -89,7 +89,7 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
Obviously this is as fragile as can be, but currently the best we can do while the panel sheets
|
||||
hide the actual features from Path and they can't be referenced directly.
|
||||
'''
|
||||
ids = string.split(sub, '.')
|
||||
ids = sub.split(".")
|
||||
holeId = int(ids[0])
|
||||
wireId = int(ids[1])
|
||||
edgeId = int(ids[2])
|
||||
|
||||
@@ -29,6 +29,10 @@ import PathScripts.PathOpGui as PathOpGui
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
import sys
|
||||
if sys.version_info.major >= 3:
|
||||
xrange = range
|
||||
|
||||
__title__ = "Base for Circular Hole based operations' UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
@@ -1019,6 +1019,10 @@ class TaskPanel:
|
||||
Draft.move(sel.Object, by)
|
||||
|
||||
def updateSelection(self):
|
||||
# Remove Job object if present in Selection: source of phantom paths
|
||||
if self.obj in FreeCADGui.Selection.getSelection():
|
||||
FreeCADGui.Selection.removeSelection(self.obj)
|
||||
|
||||
sel = FreeCADGui.Selection.getSelectionEx()
|
||||
|
||||
if len(sel) == 1 and len(sel[0].SubObjects) == 1:
|
||||
|
||||
@@ -35,6 +35,10 @@ import PathScripts.PathOp as PathOp
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
import sys
|
||||
if sys.version_info.major >= 3:
|
||||
xrange = range
|
||||
|
||||
__title__ = "Path Surface Operation"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
@@ -101,7 +101,7 @@ CURRENT_Z = 0
|
||||
|
||||
|
||||
# to distinguish python built-in open function from the one declared below
|
||||
if open.__module__ == '__builtin__':
|
||||
if open.__module__ in ['__builtin__','io']:
|
||||
pythonopen = open
|
||||
|
||||
|
||||
@@ -393,7 +393,7 @@ def drill_translate(outstring, cmd, params):
|
||||
RETRACT_Z = CURRENT_Z
|
||||
|
||||
# Recupere les valeurs des autres parametres
|
||||
drill_Speed = params['F']
|
||||
drill_Speed = params['F'] * SPEED_MULTIPLIER
|
||||
if cmd == 'G83':
|
||||
drill_Step = params['Q']
|
||||
elif cmd == 'G82':
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <Mod/Part/App/TopoShapePy.h>
|
||||
#include <App/Application.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Raytracing {
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
|
||||
|
||||
using namespace Raytracing;
|
||||
using namespace std;
|
||||
|
||||
PROPERTY_SOURCE(Raytracing::LuxFeature, Raytracing::RaySegment)
|
||||
|
||||
|
||||
@@ -5140,7 +5140,7 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
|
||||
|
||||
for (std::vector<Part::Geometry *>::const_iterator it=svals.begin(); it != svals.end(); ++it){
|
||||
Part::Geometry *geoNew = (*it)->copy();
|
||||
if(construction) {
|
||||
if(construction && geoNew->getTypeId() != Part::GeomPoint::getClassTypeId()) {
|
||||
geoNew->Construction = true;
|
||||
}
|
||||
newVals.push_back(geoNew);
|
||||
@@ -5174,11 +5174,13 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
|
||||
int sourceid = 0;
|
||||
for (std::vector< Sketcher::Constraint * >::const_iterator it= scvals.begin(); it != scvals.end(); ++it,nextcid++,sourceid++) {
|
||||
|
||||
if ((*it)->Type == Sketcher::Distance ||
|
||||
(*it)->Type == Sketcher::Radius ||
|
||||
(*it)->Type == Sketcher::Diameter ||
|
||||
(*it)->Type == Sketcher::Angle ||
|
||||
(*it)->Type == Sketcher::SnellsLaw) {
|
||||
if ((*it)->Type == Sketcher::Distance ||
|
||||
(*it)->Type == Sketcher::Radius ||
|
||||
(*it)->Type == Sketcher::Diameter ||
|
||||
(*it)->Type == Sketcher::Angle ||
|
||||
(*it)->Type == Sketcher::SnellsLaw ||
|
||||
(*it)->Type == Sketcher::DistanceX ||
|
||||
(*it)->Type == Sketcher::DistanceY ) {
|
||||
// then we link its value to the parent
|
||||
// (there is a plausible alternative for a slightly different use case to copy the expression of the parent if one is existing)
|
||||
if ((*it)->isDriving) {
|
||||
@@ -5191,45 +5193,7 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
|
||||
|
||||
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
|
||||
setExpression(Constraints.createPath(nextcid), expr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if ((*it)->Type == Sketcher::DistanceX) {
|
||||
// then we link its value to the parent
|
||||
// (there is a plausible alternative for a slightly different use case to copy the expression of the parent if one is existing)
|
||||
if ((*it)->isDriving) {
|
||||
App::ObjectIdentifier spath = psObj->Constraints.createPath(sourceid);
|
||||
|
||||
if(xinv) {
|
||||
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, std::string(1,'-') + spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
|
||||
setExpression(Constraints.createPath(nextcid), expr);
|
||||
}
|
||||
else {
|
||||
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
|
||||
|
||||
setExpression(Constraints.createPath(nextcid), expr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if ((*it)->Type == Sketcher::DistanceY ) {
|
||||
// then we link its value to the parent
|
||||
// (there is a plausible alternative for a slightly different use case to copy the expression of the parent if one is existing)
|
||||
if ((*it)->isDriving) {
|
||||
App::ObjectIdentifier spath = psObj->Constraints.createPath(sourceid);
|
||||
|
||||
if(yinv) {
|
||||
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, std::string(1,'-') + spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
|
||||
setExpression(Constraints.createPath(nextcid), expr);
|
||||
}
|
||||
else {
|
||||
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
|
||||
setExpression(Constraints.createPath(nextcid), expr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,9 +82,7 @@ void EditDatumDialog::exec(bool atCursor)
|
||||
}
|
||||
|
||||
Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
|
||||
Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
|
||||
|
||||
QDialog dlg(viewer->getGLWidget());
|
||||
QDialog dlg(mdi);
|
||||
|
||||
Ui::InsertDatum ui_ins_datum;
|
||||
ui_ins_datum.setupUi(&dlg);
|
||||
|
||||
@@ -1195,11 +1195,17 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
|
||||
return true;
|
||||
}
|
||||
case STATUS_SKETCH_UseRubberBand: {
|
||||
// Here we must use the device-pixel-ratio to compute the correct y coordinate (#0003130)
|
||||
#if QT_VERSION >= 0x050600
|
||||
qreal dpr = viewer->getGLWidget()->devicePixelRatioF();
|
||||
#else
|
||||
qreal dpr = 1;
|
||||
#endif
|
||||
newCursorPos = cursorPos;
|
||||
rubberband->setCoords(prvCursorPos.getValue()[0],
|
||||
viewer->getGLWidget()->height() - prvCursorPos.getValue()[1],
|
||||
viewer->getGLWidget()->height()*dpr - prvCursorPos.getValue()[1],
|
||||
newCursorPos.getValue()[0],
|
||||
viewer->getGLWidget()->height() - newCursorPos.getValue()[1]);
|
||||
viewer->getGLWidget()->height()*dpr - newCursorPos.getValue()[1]);
|
||||
viewer->redraw();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ known issues:
|
||||
import zipfile
|
||||
import xml.dom.minidom
|
||||
import FreeCAD as App
|
||||
import sys
|
||||
|
||||
try: import FreeCADGui
|
||||
except ValueError: gui = False
|
||||
@@ -371,7 +372,10 @@ def handleCells(cellList, actCellSheet, sList):
|
||||
if cellType == 'n':
|
||||
actCellSheet.set(ref, theValue)
|
||||
if cellType == 's':
|
||||
actCellSheet.set(ref, (sList[int(theValue)]).encode('utf8'))
|
||||
if sys.version_info.major >= 3:
|
||||
actCellSheet.set(ref, (sList[int(theValue)]))
|
||||
else:
|
||||
actCellSheet.set(ref, (sList[int(theValue)]).encode('utf8'))
|
||||
|
||||
|
||||
def handleWorkBook(theBook, sheetDict, Doc):
|
||||
|
||||
@@ -517,6 +517,7 @@ void QGIFace::buildSvgHatch()
|
||||
before.append(QString::fromStdString(SVGCOLPREFIX + SVGCOLDEFAULT));
|
||||
after.append(QString::fromStdString(SVGCOLPREFIX + m_svgCol));
|
||||
QByteArray colorXML = m_svgXML.replace(before,after);
|
||||
long int tileCount = 0;
|
||||
for (int iw = 0; iw < int(nw); iw++) {
|
||||
for (int ih = 0; ih < int(nh); ih++) {
|
||||
QGCustomSvg* tile = new QGCustomSvg();
|
||||
@@ -525,6 +526,14 @@ void QGIFace::buildSvgHatch()
|
||||
tile->setParentItem(m_rect);
|
||||
tile->setPos(iw*wTile,-h + ih*hTile);
|
||||
}
|
||||
tileCount++;
|
||||
if (tileCount > m_maxTile) {
|
||||
Base::Console().Warning("SVG tile count exceeded: %ld\n",tileCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tileCount > m_maxTile) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -611,6 +620,10 @@ void QGIFace::getParameters(void)
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/PAT");
|
||||
|
||||
m_maxSeg = hGrp->GetInt("MaxSeg",10000l);
|
||||
|
||||
hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
|
||||
m_maxTile = hGrp->GetInt("MaxSVGTile",10000l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -147,6 +147,7 @@ protected:
|
||||
std::vector<DashSpec> m_dashSpecs;
|
||||
long int m_segCount;
|
||||
long int m_maxSeg;
|
||||
long int m_maxTile;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -374,7 +374,10 @@ void QGIViewPart::drawViewPart()
|
||||
}
|
||||
newFace->isHatched(true);
|
||||
newFace->setFillMode(QGIFace::GeomHatchFill);
|
||||
newFace->setHatchScale(fGeom->ScalePattern.getValue());
|
||||
double hatchScale = fGeom->ScalePattern.getValue();
|
||||
if (hatchScale > 0.0) {
|
||||
newFace->setHatchScale(fGeom->ScalePattern.getValue());
|
||||
}
|
||||
newFace->setHatchFile(fGeom->FilePattern.getValue());
|
||||
Gui::ViewProvider* gvp = QGIView::getViewProvider(fGeom);
|
||||
ViewProviderGeomHatch* geomVp = dynamic_cast<ViewProviderGeomHatch*>(gvp);
|
||||
@@ -392,7 +395,10 @@ void QGIViewPart::drawViewPart()
|
||||
Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch);
|
||||
ViewProviderHatch* hatchVp = dynamic_cast<ViewProviderHatch*>(gvp);
|
||||
if (hatchVp != nullptr) {
|
||||
newFace->setHatchScale(hatchVp->HatchScale.getValue());
|
||||
double hatchScale = hatchVp->HatchScale.getValue();
|
||||
if (hatchScale > 0.0) {
|
||||
newFace->setHatchScale(hatchVp->HatchScale.getValue());
|
||||
}
|
||||
newFace->setHatchColor(hatchVp->HatchColor.getValue());
|
||||
}
|
||||
}
|
||||
@@ -541,7 +547,8 @@ void QGIViewPart::removePrimitives()
|
||||
for (auto& c:children) {
|
||||
QGIPrimPath* prim = dynamic_cast<QGIPrimPath*>(c);
|
||||
if (prim) {
|
||||
removeFromGroup(prim);
|
||||
prim->hide();
|
||||
// removeFromGroup(prim);
|
||||
scene()->removeItem(prim);
|
||||
delete prim;
|
||||
}
|
||||
@@ -559,11 +566,13 @@ void QGIViewPart::removeDecorations()
|
||||
QGIDecoration* decor = dynamic_cast<QGIDecoration*>(c);
|
||||
QGIMatting* mat = dynamic_cast<QGIMatting*>(c);
|
||||
if (decor) {
|
||||
removeFromGroup(decor);
|
||||
decor->hide();
|
||||
// removeFromGroup(decor);
|
||||
scene()->removeItem(decor);
|
||||
delete decor;
|
||||
} else if (mat) {
|
||||
removeFromGroup(mat);
|
||||
mat->hide();
|
||||
// removeFromGroup(mat);
|
||||
scene()->removeItem(mat);
|
||||
delete mat;
|
||||
}
|
||||
|
||||
@@ -47,8 +47,13 @@
|
||||
|
||||
using namespace TechDrawGui;
|
||||
|
||||
App::PropertyFloatConstraint::Constraints ViewProviderHatch::scaleRange = {Precision::Confusion(),
|
||||
std::numeric_limits<double>::max(),
|
||||
//scaleRange = {lowerLimit, upperLimit, stepSize}
|
||||
//original range is far too broad for drawing. causes massive loop counts.
|
||||
//App::PropertyFloatConstraint::Constraints ViewProviderHatch::scaleRange = {Precision::Confusion(),
|
||||
// std::numeric_limits<double>::max(),
|
||||
// pow(10,- Base::UnitsApi::getDecimals())};
|
||||
App::PropertyFloatConstraint::Constraints ViewProviderHatch::scaleRange = {pow(10,- Base::UnitsApi::getDecimals()),
|
||||
1000.0,
|
||||
pow(10,- Base::UnitsApi::getDecimals())};
|
||||
|
||||
|
||||
@@ -99,9 +104,11 @@ void ViewProviderHatch::onChanged(const App::Property* prop)
|
||||
{
|
||||
if ((prop == &HatchScale) ||
|
||||
(prop == &HatchColor)) {
|
||||
TechDraw::DrawViewPart* parent = getViewObject()->getSourceView();
|
||||
if (parent) {
|
||||
parent->requestPaint();
|
||||
if (HatchScale.getValue() > 0.0) {
|
||||
TechDraw::DrawViewPart* parent = getViewObject()->getSourceView();
|
||||
if (parent) {
|
||||
parent->requestPaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ Py::Object BrowserViewPy::setHtml(const Py::Tuple& args)
|
||||
PyMem_Free(HtmlCode);
|
||||
|
||||
if (myWebView)
|
||||
myWebView->setHtml(QString::fromUtf8(EncodedHtml.c_str()), QUrl(QString::fromLatin1(BaseUrl)));
|
||||
myWebView->setHtml(QString::fromUtf8(EncodedHtml.c_str()), QUrl(QString::fromUtf8(BaseUrl)));
|
||||
return Py::None();
|
||||
}
|
||||
}
|
||||
@@ -227,6 +227,11 @@ BrowserView::BrowserView(QWidget* parent)
|
||||
isLoading(false),
|
||||
textSizeMultiplier(1.0)
|
||||
{
|
||||
#if defined(QTWEBENGINE)
|
||||
// Otherwise cause crash on exit, probably due to double deletion
|
||||
setAttribute(Qt::WA_DeleteOnClose,false);
|
||||
#endif
|
||||
|
||||
view = new WebView(this);
|
||||
setCentralWidget(view);
|
||||
|
||||
@@ -322,7 +327,12 @@ void BrowserView::onLinkClicked (const QUrl & url)
|
||||
Gui::Command::doCommand(Gui::Command::Gui,q.toStdString().c_str());
|
||||
}
|
||||
// Gui::Command::doCommand(Gui::Command::Gui,"execfile('%s')",(const char*) fi.absoluteFilePath(). toLocal8Bit());
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"exec(open('%s').read())",(const char*) fi.absoluteFilePath() .toLocal8Bit());
|
||||
QString filename = fi.absoluteFilePath();
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"exec(open(unicode('%s', 'utf-8')).read())",(const char*) filename.toUtf8());
|
||||
#else
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"exec(open('%s').read())",(const char*) filename.toUtf8());
|
||||
#endif
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
QMessageBox::critical(this, tr("Error"), QString::fromUtf8(e.what()));
|
||||
|
||||
@@ -1,4 +1,36 @@
|
||||
install(FILES org.freecadweb.FreeCAD.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
||||
install(FILES org.freecadweb.FreeCAD.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
|
||||
install(FILES org.freecadweb.FreeCAD.svg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps)
|
||||
install(FILES org.freecadweb.FreeCAD.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(NOT DEFINED APPDATA_RELEASE_DATE)
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
execute_process(COMMAND git log -1 --pretty=%cd --date=short
|
||||
OUTPUT_VARIABLE APPDATA_RELEASE_DATE
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
else()
|
||||
file(TIMESTAMP "${CMAKE_SOURCE_DIR}/CMakeLists.txt" APPDATA_RELEASE_DATE "%Y-%m-%d")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
org.freecadweb.FreeCAD.appdata.xml.in
|
||||
${CMAKE_BINARY_DIR}/org.freecadweb.FreeCAD.appdata.xml
|
||||
)
|
||||
install(
|
||||
FILES ${CMAKE_BINARY_DIR}/org.freecadweb.FreeCAD.appdata.xml
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo
|
||||
)
|
||||
|
||||
install(
|
||||
FILES org.freecadweb.FreeCAD.desktop
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications
|
||||
)
|
||||
|
||||
install(
|
||||
FILES org.freecadweb.FreeCAD.svg
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps
|
||||
)
|
||||
|
||||
install(
|
||||
FILES org.freecadweb.FreeCAD.xml
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mime/packages
|
||||
)
|
||||
|
||||
+2
-2
@@ -29,8 +29,8 @@
|
||||
<url type="help">https://forum.freecadweb.org</url>
|
||||
<url type="donation">https://www.freecadweb.org/wiki/Donate</url>
|
||||
<update_contact>yorik_AT_uncreated.net</update_contact>
|
||||
<content_rating type="oars-1.1" />
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="0.17" date="2018-04-06"></release>
|
||||
<release version="@PACKAGE_VERSION@" date="@APPDATA_RELEASE_DATE@"/>
|
||||
</releases>
|
||||
</component>
|
||||
Reference in New Issue
Block a user