Compare commits
53 Commits
fixSignCommand
...
0.18.4
| Author | SHA1 | Date | |
|---|---|---|---|
| 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.
@@ -1529,7 +1529,11 @@ void Application::initConfig(int argc, char ** argv)
|
|||||||
PyImport_AppendInittab ("FreeCAD", init_freecad_module);
|
PyImport_AppendInittab ("FreeCAD", init_freecad_module);
|
||||||
PyImport_AppendInittab ("__FreeCADBase__", init_freecad_base_module);
|
PyImport_AppendInittab ("__FreeCADBase__", init_freecad_base_module);
|
||||||
#endif
|
#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
|
// Parse the options that have impact on the init process
|
||||||
ParseOptions(argc,argv);
|
ParseOptions(argc,argv);
|
||||||
|
|||||||
@@ -3031,7 +3031,13 @@ void Document::breakDependency(DocumentObject* pcObject, bool clear)
|
|||||||
std::vector<App::ObjectIdentifier> paths;
|
std::vector<App::ObjectIdentifier> paths;
|
||||||
pcObject->ExpressionEngine.getPathsToDocumentObject(it->second, paths);
|
pcObject->ExpressionEngine.getPathsToDocumentObject(it->second, paths);
|
||||||
for (std::vector<App::ObjectIdentifier>::iterator jt = paths.begin(); jt != paths.end(); ++jt) {
|
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();
|
onSettingDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentObject::onAboutToRemoveProperty(const char* prop)
|
void DocumentObject::onAboutToRemoveProperty(const char* name)
|
||||||
{
|
{
|
||||||
if (_pDoc)
|
if (_pDoc) {
|
||||||
_pDoc->removePropertyOfObject(this, prop);
|
_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)
|
void DocumentObject::onBeforeChange(const Property* prop)
|
||||||
|
|||||||
@@ -1062,6 +1062,7 @@ boost::any ObjectIdentifier::getValue() const
|
|||||||
|
|
||||||
destructor d1(pyvalue);
|
destructor d1(pyvalue);
|
||||||
|
|
||||||
|
Base::PyGILStateLocker locker;
|
||||||
if (!pyvalue)
|
if (!pyvalue)
|
||||||
throw Base::RuntimeError("Failed to get property value.");
|
throw Base::RuntimeError("Failed to get property value.");
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
@@ -1078,12 +1079,12 @@ boost::any ObjectIdentifier::getValue() const
|
|||||||
return boost::any(PyString_AsString(pyvalue));
|
return boost::any(PyString_AsString(pyvalue));
|
||||||
#endif
|
#endif
|
||||||
else if (PyUnicode_Check(pyvalue)) {
|
else if (PyUnicode_Check(pyvalue)) {
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
return boost::any(PyUnicode_AsUTF8(pyvalue));
|
||||||
|
#else
|
||||||
PyObject * s = PyUnicode_AsUTF8String(pyvalue);
|
PyObject * s = PyUnicode_AsUTF8String(pyvalue);
|
||||||
destructor d2(s);
|
destructor d2(s);
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
return boost::any(PyUnicode_AsUTF8(s));
|
|
||||||
#else
|
|
||||||
return boost::any(PyString_AsString(s));
|
return boost::any(PyString_AsString(s));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,13 +354,15 @@ void InterpreterSingleton::runInteractiveString(const char *sCmd)
|
|||||||
PyErr_Fetch(&errobj, &errdata, &errtraceback);
|
PyErr_Fetch(&errobj, &errdata, &errtraceback);
|
||||||
|
|
||||||
RuntimeError exc(""); // do not use PyException since this clears the error indicator
|
RuntimeError exc(""); // do not use PyException since this clears the error indicator
|
||||||
|
if (errdata) {
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
if (PyUnicode_Check(errdata))
|
if (PyUnicode_Check(errdata))
|
||||||
exc.setMessage(PyUnicode_AsUTF8(errdata));
|
exc.setMessage(PyUnicode_AsUTF8(errdata));
|
||||||
#else
|
#else
|
||||||
if (PyString_Check(errdata))
|
if (PyString_Check(errdata))
|
||||||
exc.setMessage(PyString_AsString(errdata));
|
exc.setMessage(PyString_AsString(errdata));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
PyErr_Restore(errobj, errdata, errtraceback);
|
PyErr_Restore(errobj, errdata, errtraceback);
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
|||||||
@@ -2033,25 +2033,25 @@ namespace Py
|
|||||||
}
|
}
|
||||||
|
|
||||||
String()
|
String()
|
||||||
: SeqBase<Char>( PyUnicode_FromString( "" ) )
|
: SeqBase<Char>( PyUnicode_FromString( "" ), true )
|
||||||
{
|
{
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
String( const char *latin1 )
|
String( const char *latin1 )
|
||||||
: SeqBase<Char>( PyUnicode_FromString( latin1 ) )
|
: SeqBase<Char>( PyUnicode_FromString( latin1 ), true )
|
||||||
{
|
{
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
String( const std::string &latin1 )
|
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();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
String( const char *latin1, Py_ssize_t size )
|
String( const char *latin1, Py_ssize_t size )
|
||||||
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1, size ) )
|
: SeqBase<Char>( PyUnicode_FromStringAndSize( latin1, size ), true )
|
||||||
{
|
{
|
||||||
validate();
|
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
|
// does the similar as the method above except that this method does not resize the resulting pixmap
|
||||||
int x = 0, y = 0;
|
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)
|
switch (pos)
|
||||||
{
|
{
|
||||||
case TopLeft:
|
case TopLeft:
|
||||||
break;
|
break;
|
||||||
case TopRight:
|
case TopRight:
|
||||||
x = p1.width () - p2.width ();
|
x = p1.width ()/dpr1 - p2.width ()/dpr2;
|
||||||
break;
|
break;
|
||||||
case BottomLeft:
|
case BottomLeft:
|
||||||
y = p1.height() - p2.height();
|
y = p1.height()/dpr1 - p2.height()/dpr2;
|
||||||
break;
|
break;
|
||||||
case BottomRight:
|
case BottomRight:
|
||||||
x = p1.width () - p2.width ();
|
x = p1.width ()/dpr1 - p2.width ()/dpr2;
|
||||||
y = p1.height() - p2.height();
|
y = p1.height()/dpr1 - p2.height()/dpr2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-12
@@ -1092,9 +1092,15 @@ void StdCmdDelete::activated(int iMsg)
|
|||||||
// handle the view provider
|
// handle the view provider
|
||||||
Gui::getMainWindow()->setUpdatesEnabled(false);
|
Gui::getMainWindow()->setUpdatesEnabled(false);
|
||||||
|
|
||||||
(*it)->openTransaction("Delete");
|
try {
|
||||||
vpedit->onDelete(ft->getSubNames());
|
(*it)->openTransaction("Delete");
|
||||||
(*it)->commitTransaction();
|
vpedit->onDelete(ft->getSubNames());
|
||||||
|
(*it)->commitTransaction();
|
||||||
|
}
|
||||||
|
catch (const Base::Exception& e) {
|
||||||
|
(*it)->abortTransaction();
|
||||||
|
e.ReportException();
|
||||||
|
}
|
||||||
|
|
||||||
Gui::getMainWindow()->setUpdatesEnabled(true);
|
Gui::getMainWindow()->setUpdatesEnabled(true);
|
||||||
Gui::getMainWindow()->update();
|
Gui::getMainWindow()->update();
|
||||||
@@ -1171,18 +1177,24 @@ void StdCmdDelete::activated(int iMsg)
|
|||||||
|
|
||||||
if (autoDeletion) {
|
if (autoDeletion) {
|
||||||
Gui::getMainWindow()->setUpdatesEnabled(false);
|
Gui::getMainWindow()->setUpdatesEnabled(false);
|
||||||
(*it)->openTransaction("Delete");
|
try {
|
||||||
for (std::vector<Gui::SelectionObject>::iterator ft = sel.begin(); ft != sel.end(); ++ft) {
|
(*it)->openTransaction("Delete");
|
||||||
Gui::ViewProvider* vp = pGuiDoc->getViewProvider(ft->getObject());
|
for (std::vector<Gui::SelectionObject>::iterator ft = sel.begin(); ft != sel.end(); ++ft) {
|
||||||
if (vp) {
|
Gui::ViewProvider* vp = pGuiDoc->getViewProvider(ft->getObject());
|
||||||
// ask the ViewProvider if it wants to do some clean up
|
if (vp) {
|
||||||
if (vp->onDelete(ft->getSubNames())) {
|
// ask the ViewProvider if it wants to do some clean up
|
||||||
doCommand(Doc,"App.getDocument(\"%s\").removeObject(\"%s\")"
|
if (vp->onDelete(ft->getSubNames())) {
|
||||||
,(*it)->getName(), ft->getFeatName());
|
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()->setUpdatesEnabled(true);
|
||||||
Gui::getMainWindow()->update();
|
Gui::getMainWindow()->update();
|
||||||
|
|||||||
@@ -199,6 +199,8 @@ QString FileDialog::getSaveFileName (QWidget * parent, const QString & caption,
|
|||||||
dlg.setDirectory(dirName);
|
dlg.setDirectory(dirName);
|
||||||
dlg.setOptions(options);
|
dlg.setOptions(options);
|
||||||
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
||||||
|
if (selectedFilter && !selectedFilter->isEmpty())
|
||||||
|
dlg.selectNameFilter(*selectedFilter);
|
||||||
dlg.onSelectedFilter(dlg.selectedNameFilter());
|
dlg.onSelectedFilter(dlg.selectedNameFilter());
|
||||||
dlg.setNameFilterDetailsVisible(true);
|
dlg.setNameFilterDetailsVisible(true);
|
||||||
dlg.setConfirmOverwrite(true);
|
dlg.setConfirmOverwrite(true);
|
||||||
@@ -295,6 +297,8 @@ QString FileDialog::getOpenFileName(QWidget * parent, const QString & caption, c
|
|||||||
dlg.setOptions(options);
|
dlg.setOptions(options);
|
||||||
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
||||||
dlg.setNameFilterDetailsVisible(true);
|
dlg.setNameFilterDetailsVisible(true);
|
||||||
|
if (selectedFilter && !selectedFilter->isEmpty())
|
||||||
|
dlg.selectNameFilter(*selectedFilter);
|
||||||
if (dlg.exec() == QDialog::Accepted) {
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
if (selectedFilter)
|
if (selectedFilter)
|
||||||
*selectedFilter = dlg.selectedNameFilter();
|
*selectedFilter = dlg.selectedNameFilter();
|
||||||
@@ -369,6 +373,8 @@ QStringList FileDialog::getOpenFileNames (QWidget * parent, const QString & capt
|
|||||||
dlg.setOptions(options);
|
dlg.setOptions(options);
|
||||||
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
dlg.setNameFilters(filter.split(QLatin1String(";;")));
|
||||||
dlg.setNameFilterDetailsVisible(true);
|
dlg.setNameFilterDetailsVisible(true);
|
||||||
|
if (selectedFilter && !selectedFilter->isEmpty())
|
||||||
|
dlg.selectNameFilter(*selectedFilter);
|
||||||
if (dlg.exec() == QDialog::Accepted) {
|
if (dlg.exec() == QDialog::Accepted) {
|
||||||
if (selectedFilter)
|
if (selectedFilter)
|
||||||
*selectedFilter = dlg.selectedNameFilter();
|
*selectedFilter = dlg.selectedNameFilter();
|
||||||
|
|||||||
@@ -98,6 +98,12 @@ void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window)
|
|||||||
mainWindow = window;
|
mainWindow = window;
|
||||||
|
|
||||||
#if defined(Q_OS_LINUX) && defined(SPNAV_FOUND)
|
#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) {
|
if (spnav_x11_open(QX11Info::display(), window->winId()) == -1) {
|
||||||
Base::Console().Log("Couldn't connect to spacenav daemon\n");
|
Base::Console().Log("Couldn't connect to spacenav daemon\n");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -390,7 +390,16 @@ int PolyPickerSelection::locationEvent(const SoLocation2Event* const, const QPoi
|
|||||||
|
|
||||||
if (polyline.isWorking()) {
|
if (polyline.isWorking()) {
|
||||||
// check the position
|
// check the position
|
||||||
|
#if QT_VERSION >= 0x050600
|
||||||
|
qreal dpr = _pcView3D->getGLWidget()->devicePixelRatioF();
|
||||||
|
#else
|
||||||
|
qreal dpr = 1.0;
|
||||||
|
#endif
|
||||||
QRect r = _pcView3D->getGLWidget()->rect();
|
QRect r = _pcView3D->getGLWidget()->rect();
|
||||||
|
if (dpr != 1.0) {
|
||||||
|
r.setHeight(r.height()*dpr);
|
||||||
|
r.setWidth(r.width()*dpr);
|
||||||
|
}
|
||||||
|
|
||||||
if (!r.contains(clPoint)) {
|
if (!r.contains(clPoint)) {
|
||||||
if (clPoint.x() < r.left())
|
if (clPoint.x() < r.left())
|
||||||
@@ -599,7 +608,16 @@ int FreehandSelection::locationEvent(const SoLocation2Event* const e, const QPoi
|
|||||||
|
|
||||||
if (polyline.isWorking()) {
|
if (polyline.isWorking()) {
|
||||||
// check the position
|
// check the position
|
||||||
|
#if QT_VERSION >= 0x050600
|
||||||
|
qreal dpr = _pcView3D->getGLWidget()->devicePixelRatioF();
|
||||||
|
#else
|
||||||
|
qreal dpr = 1.0;
|
||||||
|
#endif
|
||||||
QRect r = _pcView3D->getGLWidget()->rect();
|
QRect r = _pcView3D->getGLWidget()->rect();
|
||||||
|
if (dpr != 1.0) {
|
||||||
|
r.setHeight(r.height()*dpr);
|
||||||
|
r.setWidth(r.width()*dpr);
|
||||||
|
}
|
||||||
|
|
||||||
if (!r.contains(clPoint)) {
|
if (!r.contains(clPoint)) {
|
||||||
if (clPoint.x() < r.left())
|
if (clPoint.x() < r.left())
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ QByteArray PythonOnlineHelp::loadResource(const QString& filename) const
|
|||||||
dict = PyDict_Copy(dict);
|
dict = PyDict_Copy(dict);
|
||||||
|
|
||||||
QByteArray cmd =
|
QByteArray cmd =
|
||||||
"import string, os, sys, pydoc, pkgutil\n"
|
"import os, sys, pydoc, pkgutil\n"
|
||||||
"\n"
|
"\n"
|
||||||
"class FreeCADDoc(pydoc.HTMLDoc):\n"
|
"class FreeCADDoc(pydoc.HTMLDoc):\n"
|
||||||
" def index(self, dir, shadowed=None):\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"
|
" ret = pydoc.html.index(dir, seen)\n"
|
||||||
" if ret != None:\n"
|
" if ret != None:\n"
|
||||||
" indices.append(ret)\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"
|
"<font color=\"#909090\" face=\"helvetica, arial\"><strong>\n"
|
||||||
"pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'''\n"
|
"pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'''\n"
|
||||||
"htmldocument=pydoc.html.page(title,contents)\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 */
|
if (PyErr_Occurred()) { /* get latest python exception information */
|
||||||
PyObject *errobj, *errdata, *errtraceback;
|
PyObject *errobj, *errdata, *errtraceback;
|
||||||
PyErr_Fetch(&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");
|
PyObject* value = PyDict_GetItemString(errdata, "swhat");
|
||||||
if (value) {
|
if (value) {
|
||||||
Base::RuntimeError e;
|
Base::RuntimeError e;
|
||||||
|
|||||||
@@ -477,7 +477,9 @@ void View3DInventor::printPreview()
|
|||||||
{
|
{
|
||||||
QPrinter printer(QPrinter::ScreenResolution);
|
QPrinter printer(QPrinter::ScreenResolution);
|
||||||
printer.setFullPage(true);
|
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);
|
printer.setOrientation(QPrinter::Landscape);
|
||||||
|
|
||||||
QPrintPreviewDialog dlg(&printer, this);
|
QPrintPreviewDialog dlg(&printer, this);
|
||||||
|
|||||||
+58
-19
@@ -232,6 +232,28 @@ Py::Object qt_wrapInstance(qttype object, const char* className,
|
|||||||
return func.apply(arguments);
|
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)
|
void* qt_getCppPointer(const Py::Object& pyobject, const char* shiboken, const char* unwrap)
|
||||||
{
|
{
|
||||||
// https://github.com/PySide/Shiboken/blob/master/shibokenmodule/typesystem_shiboken.xml
|
// 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)
|
void PythonWrapper::createChildrenNameAttributes(PyObject* root, QObject* object)
|
||||||
{
|
{
|
||||||
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
|
|
||||||
Q_FOREACH (QObject* child, object->children()) {
|
Q_FOREACH (QObject* child, object->children()) {
|
||||||
const QByteArray name = child->objectName().toLocal8Bit();
|
const QByteArray name = child->objectName().toLocal8Bit();
|
||||||
|
|
||||||
if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) {
|
if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) {
|
||||||
bool hasAttr = PyObject_HasAttrString(root, name.constData());
|
bool hasAttr = PyObject_HasAttrString(root, name.constData());
|
||||||
if (!hasAttr) {
|
if (!hasAttr) {
|
||||||
#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2)
|
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
|
||||||
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], child));
|
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython(reinterpret_cast<SbkObjectType*>(Shiboken::SbkType<QObject>()), child));
|
||||||
#else
|
|
||||||
Shiboken::AutoDecRef pyChild(Shiboken::Conversions::pointerToPython((SbkObjectType*)SbkPySide_QtCoreTypes[SBK_QOBJECT_IDX], child));
|
|
||||||
#endif
|
|
||||||
PyObject_SetAttrString(root, name.constData(), pyChild);
|
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);
|
||||||
}
|
}
|
||||||
createChildrenNameAttributes(root, child);
|
createChildrenNameAttributes(root, child);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
Q_UNUSED(root);
|
|
||||||
Q_UNUSED(object);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonWrapper::setParent(PyObject* pyWdg, QObject* parent)
|
void PythonWrapper::setParent(PyObject* pyWdg, QObject* parent)
|
||||||
{
|
{
|
||||||
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
|
#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE)
|
||||||
if (parent) {
|
if (parent) {
|
||||||
#if defined (HAVE_SHIBOKEN2) && defined(HAVE_PYSIDE2)
|
Shiboken::AutoDecRef pyParent(Shiboken::Conversions::pointerToPython(reinterpret_cast<SbkObjectType*>(Shiboken::SbkType<QWidget>()), parent));
|
||||||
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::Object::setParent(pyParent, pyWdg);
|
Shiboken::Object::setParent(pyParent, pyWdg);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -680,7 +713,10 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
|
|||||||
str << "import pyside2uic\n"
|
str << "import pyside2uic\n"
|
||||||
<< "from PySide2 import QtCore, QtGui, QtWidgets\n"
|
<< "from PySide2 import QtCore, QtGui, QtWidgets\n"
|
||||||
<< "import xml.etree.ElementTree as xml\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"
|
<< "\n"
|
||||||
<< "uiFile = \"" << file.c_str() << "\"\n"
|
<< "uiFile = \"" << file.c_str() << "\"\n"
|
||||||
<< "parsed = xml.parse(uiFile)\n"
|
<< "parsed = xml.parse(uiFile)\n"
|
||||||
@@ -691,7 +727,7 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
|
|||||||
<< " frame = {}\n"
|
<< " frame = {}\n"
|
||||||
<< " pyside2uic.compileUi(f, o, indent=0)\n"
|
<< " pyside2uic.compileUi(f, o, indent=0)\n"
|
||||||
<< " pyc = compile(o.getvalue(), '<string>', 'exec')\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"
|
<< " #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"
|
<< " form_class = frame['Ui_%s'%form_class]\n"
|
||||||
<< " base_class = eval('QtWidgets.%s'%widget_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"
|
str << "import pysideuic\n"
|
||||||
<< "from PySide import QtCore, QtGui\n"
|
<< "from PySide import QtCore, QtGui\n"
|
||||||
<< "import xml.etree.ElementTree as xml\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"
|
<< "\n"
|
||||||
<< "uiFile = \"" << file.c_str() << "\"\n"
|
<< "uiFile = \"" << file.c_str() << "\"\n"
|
||||||
<< "parsed = xml.parse(uiFile)\n"
|
<< "parsed = xml.parse(uiFile)\n"
|
||||||
@@ -710,7 +749,7 @@ Py::Object PySideUicModule::loadUiType(const Py::Tuple& args)
|
|||||||
<< " frame = {}\n"
|
<< " frame = {}\n"
|
||||||
<< " pysideuic.compileUi(f, o, indent=0)\n"
|
<< " pysideuic.compileUi(f, o, indent=0)\n"
|
||||||
<< " pyc = compile(o.getvalue(), '<string>', 'exec')\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"
|
<< " #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"
|
<< " form_class = frame['Ui_%s'%form_class]\n"
|
||||||
<< " base_class = eval('QtGui.%s'%widget_class)\n";
|
<< " base_class = eval('QtGui.%s'%widget_class)\n";
|
||||||
|
|||||||
@@ -577,14 +577,18 @@ class UpdateWorker(QtCore.QThread):
|
|||||||
name = re.findall("title=\"(.*?) @",l)[0]
|
name = re.findall("title=\"(.*?) @",l)[0]
|
||||||
self.info_label.emit(name)
|
self.info_label.emit(name)
|
||||||
#url = re.findall("title=\"(.*?) @",l)[0]
|
#url = re.findall("title=\"(.*?) @",l)[0]
|
||||||
url = "https://github.com/" + re.findall("href=\"\/(.*?)\/tree",l)[0]
|
try:
|
||||||
addondir = moddir + os.sep + name
|
url = "https://github.com/" + re.findall("href=\"\/(.*?)\/tree",l)[0]
|
||||||
#print ("found:",name," at ",url)
|
except:
|
||||||
if not os.path.exists(addondir):
|
pass
|
||||||
state = 0
|
|
||||||
else:
|
else:
|
||||||
state = 1
|
addondir = moddir + os.sep + name
|
||||||
repos.append([name,url,state])
|
#print ("found:",name," at ",url)
|
||||||
|
if not os.path.exists(addondir):
|
||||||
|
state = 0
|
||||||
|
else:
|
||||||
|
state = 1
|
||||||
|
repos.append([name,url,state])
|
||||||
if not repos:
|
if not repos:
|
||||||
self.info_label.emit(translate("AddonsInstaller", "Unable to download addon list."))
|
self.info_label.emit(translate("AddonsInstaller", "Unable to download addon list."))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -250,6 +250,7 @@ class _ArchMaterial:
|
|||||||
"The Material object"
|
"The Material object"
|
||||||
|
|
||||||
def __init__(self,obj):
|
def __init__(self,obj):
|
||||||
|
|
||||||
self.Type = "Material"
|
self.Type = "Material"
|
||||||
obj.Proxy = self
|
obj.Proxy = self
|
||||||
obj.addProperty("App::PropertyString","Description","Arch",QT_TRANSLATE_NOOP("App::Property","A description for this material"))
|
obj.addProperty("App::PropertyString","Description","Arch",QT_TRANSLATE_NOOP("App::Property","A description for this material"))
|
||||||
@@ -259,7 +260,8 @@ class _ArchMaterial:
|
|||||||
obj.addProperty("App::PropertyColor","Color","Arch",QT_TRANSLATE_NOOP("App::Property","The color of this material"))
|
obj.addProperty("App::PropertyColor","Color","Arch",QT_TRANSLATE_NOOP("App::Property","The color of this material"))
|
||||||
|
|
||||||
def onChanged(self,obj,prop):
|
def onChanged(self,obj,prop):
|
||||||
d = None
|
|
||||||
|
d = obj.Material
|
||||||
if prop == "Material":
|
if prop == "Material":
|
||||||
if "DiffuseColor" in obj.Material:
|
if "DiffuseColor" in obj.Material:
|
||||||
c = tuple([float(f) for f in obj.Material['DiffuseColor'].strip("()").split(",")])
|
c = tuple([float(f) for f in obj.Material['DiffuseColor'].strip("()").split(",")])
|
||||||
@@ -283,52 +285,51 @@ class _ArchMaterial:
|
|||||||
if hasattr(obj,"Description"):
|
if hasattr(obj,"Description"):
|
||||||
if obj.Description != obj.Material["Description"]:
|
if obj.Description != obj.Material["Description"]:
|
||||||
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":
|
elif prop == "Color":
|
||||||
if hasattr(obj,"Color"):
|
if hasattr(obj,"Color"):
|
||||||
if obj.Material:
|
val = str(obj.Color[:3])
|
||||||
d = obj.Material
|
if "DiffuseColor" in d:
|
||||||
val = str(obj.Color[:3])
|
if d["DiffuseColor"] == val:
|
||||||
if "DiffuseColor" in d:
|
return
|
||||||
if d["DiffuseColor"] == val:
|
d["DiffuseColor"] = val
|
||||||
return
|
|
||||||
d["DiffuseColor"] = val
|
|
||||||
elif prop == "Transparency":
|
elif prop == "Transparency":
|
||||||
if hasattr(obj,"Transparency"):
|
if hasattr(obj,"Transparency"):
|
||||||
if obj.Material:
|
val = str(obj.Transparency)
|
||||||
d = obj.Material
|
if "Transparency" in d:
|
||||||
val = str(obj.Transparency)
|
if d["Transparency"] == val:
|
||||||
if "Transparency" in d:
|
return
|
||||||
if d["Transparency"] == val:
|
d["Transparency"] = val
|
||||||
return
|
|
||||||
d["Transparency"] = val
|
|
||||||
elif prop == "ProductURL":
|
elif prop == "ProductURL":
|
||||||
if hasattr(obj,"ProductURL"):
|
if hasattr(obj,"ProductURL"):
|
||||||
if obj.Material:
|
val = obj.ProductURL
|
||||||
d = obj.Material
|
if "ProductURL" in d:
|
||||||
val = obj.ProductURL
|
if d["ProductURL"] == val:
|
||||||
if "ProductURL" in d:
|
return
|
||||||
if d["ProductURL"] == val:
|
obj.Material["ProductURL"] = val
|
||||||
return
|
|
||||||
obj.Material["ProductURL"] = val
|
|
||||||
elif prop == "StandardCode":
|
elif prop == "StandardCode":
|
||||||
if hasattr(obj,"StandardCode"):
|
if hasattr(obj,"StandardCode"):
|
||||||
if obj.Material:
|
val = obj.StandardCode
|
||||||
d = obj.Material
|
if "StandardCode" in d:
|
||||||
val = obj.StandardCode
|
if d["StandardCode"] == val:
|
||||||
if "StandardCode" in d:
|
return
|
||||||
if d["StandardCode"] == val:
|
d["StandardCode"] = val
|
||||||
return
|
|
||||||
d["StandardCode"] = val
|
|
||||||
elif prop == "Description":
|
elif prop == "Description":
|
||||||
if hasattr(obj,"Description"):
|
if hasattr(obj,"Description"):
|
||||||
if obj.Material:
|
val = obj.Description
|
||||||
d = obj.Material
|
if "Description" in d:
|
||||||
val = obj.Description
|
if d["Description"] == val:
|
||||||
if "Description" in d:
|
return
|
||||||
if d["Description"] == val:
|
d["Description"] = val
|
||||||
return
|
if d and (d != obj.Material):
|
||||||
d["Description"] = val
|
|
||||||
if d:
|
|
||||||
obj.Material = d
|
obj.Material = d
|
||||||
if FreeCAD.GuiUp:
|
if FreeCAD.GuiUp:
|
||||||
import FreeCADGui
|
import FreeCADGui
|
||||||
|
|||||||
@@ -674,8 +674,12 @@ class _Roof(ArchComponent.Component):
|
|||||||
if obj.Base.Shape.Solids:
|
if obj.Base.Shape.Solids:
|
||||||
return obj.Shape
|
return obj.Shape
|
||||||
else :
|
else :
|
||||||
if self.sub:
|
if hasattr(self,"sub"):
|
||||||
return self.sub
|
if self.sub:
|
||||||
|
return self.sub
|
||||||
|
else :
|
||||||
|
self.execute(obj)
|
||||||
|
return self.sub
|
||||||
else :
|
else :
|
||||||
self.execute(obj)
|
self.execute(obj)
|
||||||
return self.sub
|
return self.sub
|
||||||
|
|||||||
+17
-17
@@ -195,7 +195,7 @@ def export(exportList,filename):
|
|||||||
outfile.close()
|
outfile.close()
|
||||||
FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + " " + decode(filename) + "\n")
|
FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + " " + decode(filename) + "\n")
|
||||||
if materials:
|
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("# FreeCAD v" + ver[0] + "." + ver[1] + " build" + ver[2] + " Arch module\n")
|
||||||
outfile.write("# http://www.freecadweb.org\n")
|
outfile.write("# http://www.freecadweb.org\n")
|
||||||
kinds = {"AmbientColor":"Ka ","DiffuseColor":"Kd ","SpecularColor":"Ks ","EmissiveColor":"Ke ","Transparency":"d "}
|
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")
|
FreeCAD.Console.PrintMessage(translate("Arch","Successfully written") + ' ' + decode(filenamemtl) + "\n")
|
||||||
|
|
||||||
|
|
||||||
def decode(name):
|
#def decode(name):
|
||||||
"decodes encoded strings"
|
# "decodes encoded strings"
|
||||||
try:
|
# try:
|
||||||
decodedName = (name.decode("utf8"))
|
# decodedName = (name.decode("utf8"))
|
||||||
except UnicodeDecodeError:
|
# except UnicodeDecodeError:
|
||||||
try:
|
# try:
|
||||||
decodedName = (name.decode("latin1"))
|
# decodedName = (name.decode("latin1"))
|
||||||
except UnicodeDecodeError:
|
# except UnicodeDecodeError:
|
||||||
FreeCAD.Console.PrintError(translate("Arch","Error: Couldn't determine character encoding"))
|
# FreeCAD.Console.PrintError(translate("Arch","Error: Couldn't determine character encoding"))
|
||||||
decodedName = name
|
# decodedName = name
|
||||||
return decodedName
|
# return decodedName
|
||||||
|
|
||||||
def open(filename):
|
def open(filename):
|
||||||
"called when freecad wants to open a file"
|
"called when freecad wants to open a file"
|
||||||
docname = (os.path.splitext(os.path.basename(filename))[0]).encode("utf8")
|
docname = (os.path.splitext(os.path.basename(filename))[0])
|
||||||
doc = FreeCAD.newDocument(docname)
|
doc = FreeCAD.newDocument(docname.encode("utf8"))
|
||||||
doc.Label = decode(docname)
|
doc.Label = docname
|
||||||
return insert(filename,doc.Name)
|
return insert(filename,doc.Name)
|
||||||
|
|
||||||
def insert(filename,docname):
|
def insert(filename,docname):
|
||||||
@@ -246,7 +246,7 @@ def insert(filename,docname):
|
|||||||
doc = FreeCAD.newDocument(docname)
|
doc = FreeCAD.newDocument(docname)
|
||||||
FreeCAD.ActiveDocument = doc
|
FreeCAD.ActiveDocument = doc
|
||||||
|
|
||||||
with pythonopen(filename,"rb") as infile:
|
with pythonopen(filename,"r") as infile:
|
||||||
verts = []
|
verts = []
|
||||||
facets = []
|
facets = []
|
||||||
activeobject = None
|
activeobject = None
|
||||||
@@ -257,7 +257,7 @@ def insert(filename,docname):
|
|||||||
if line[:7] == "mtllib ":
|
if line[:7] == "mtllib ":
|
||||||
matlib = os.path.join(os.path.dirname(filename),line[7:])
|
matlib = os.path.join(os.path.dirname(filename),line[7:])
|
||||||
if os.path.exists(matlib):
|
if os.path.exists(matlib):
|
||||||
with pythonopen(matlib,"rb") as matfile:
|
with pythonopen(matlib,"r") as matfile:
|
||||||
mname = None
|
mname = None
|
||||||
color = None
|
color = None
|
||||||
trans = None
|
trans = None
|
||||||
|
|||||||
@@ -87,22 +87,13 @@ def errorDXFLib(gui):
|
|||||||
if gui:
|
if gui:
|
||||||
from PySide import QtGui, QtCore
|
from PySide import QtGui, QtCore
|
||||||
from DraftTools import translate
|
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
|
Please install the dxf Library addon manually
|
||||||
from menu Tools -> Addon Manager""")
|
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)
|
QtGui.QMessageBox.information(None,"",message)
|
||||||
else:
|
else:
|
||||||
FreeCAD.Console.PrintWarning("The DXF import/export libraries needed by FreeCAD to handle the DXF format are not installed.\n")
|
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")
|
||||||
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")
|
|
||||||
break
|
break
|
||||||
progressbar.stop()
|
progressbar.stop()
|
||||||
sys.path.append(FreeCAD.ConfigGet("UserAppData"))
|
sys.path.append(FreeCAD.ConfigGet("UserAppData"))
|
||||||
@@ -110,17 +101,7 @@ http://www.freecadweb.org/wiki/Dxf_Importer_Install""")
|
|||||||
if gui:
|
if gui:
|
||||||
from PySide import QtGui, QtCore
|
from PySide import QtGui, QtCore
|
||||||
from DraftTools import translate
|
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
|
||||||
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
|
|
||||||
the DXF format were not found on this system.
|
the DXF format were not found on this system.
|
||||||
Please either enable FreeCAD to download these libraries:
|
Please either enable FreeCAD to download these libraries:
|
||||||
1 - Load Draft workbench
|
1 - Load Draft workbench
|
||||||
|
|||||||
@@ -295,14 +295,14 @@ def fill_femresult_mechanical(res_obj, result_set):
|
|||||||
if len(Peeq) > 0:
|
if len(Peeq) > 0:
|
||||||
if len(Peeq.values()) != len(disp.values()):
|
if len(Peeq.values()) != len(disp.values()):
|
||||||
Pe = []
|
Pe = []
|
||||||
Pe_extra_nodes = Peeq.values()
|
Pe_extra_nodes = list(Peeq.values())
|
||||||
nodes = len(disp.values())
|
nodes = len(disp.values())
|
||||||
for i in range(nodes):
|
for i in range(nodes):
|
||||||
Pe_value = Pe_extra_nodes[i]
|
Pe_value = Pe_extra_nodes[i]
|
||||||
Pe.append(Pe_value)
|
Pe.append(Pe_value)
|
||||||
res_obj.Peeq = Pe
|
res_obj.Peeq = Pe
|
||||||
else:
|
else:
|
||||||
res_obj.Peeq = Peeq.values()
|
res_obj.Peeq = list(Peeq.values())
|
||||||
|
|
||||||
# fill res_obj.Temperature if they exist
|
# 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
|
# 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) > 0:
|
||||||
if len(Temperature.values()) != len(disp.values()):
|
if len(Temperature.values()) != len(disp.values()):
|
||||||
Temp = []
|
Temp = []
|
||||||
Temp_extra_nodes = Temperature.values()
|
Temp_extra_nodes = list(Temperature.values())
|
||||||
nodes = len(disp.values())
|
nodes = len(disp.values())
|
||||||
for i in range(nodes):
|
for i in range(nodes):
|
||||||
Temp_value = Temp_extra_nodes[i]
|
Temp_value = Temp_extra_nodes[i]
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ __url__ = "http://www.freecadweb.org"
|
|||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import os.path
|
import os.path
|
||||||
|
import sys
|
||||||
|
|
||||||
import femtools.femutils as femutils
|
import femtools.femutils as femutils
|
||||||
|
|
||||||
from .. import run
|
from .. import run
|
||||||
@@ -112,7 +114,10 @@ class Solve(run.Solve):
|
|||||||
def _updateOutput(self, output):
|
def _updateOutput(self, output):
|
||||||
if self.solver.ElmerOutput is None:
|
if self.solver.ElmerOutput is None:
|
||||||
self._createOutput()
|
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):
|
def _createOutput(self):
|
||||||
self.solver.ElmerOutput = self.analysis.Document.addObject(
|
self.solver.ElmerOutput = self.analysis.Document.addObject(
|
||||||
|
|||||||
@@ -536,11 +536,11 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject):
|
|||||||
ccx_path = FreeCAD.getHomePath() + "bin/ccx.exe"
|
ccx_path = FreeCAD.getHomePath() + "bin/ccx.exe"
|
||||||
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx").SetString("ccxBinaryPath", ccx_path)
|
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Ccx").SetString("ccxBinaryPath", ccx_path)
|
||||||
self.ccx_binary = ccx_path
|
self.ccx_binary = ccx_path
|
||||||
elif system() == "Linux":
|
elif system() in ("Linux", "Darwin"):
|
||||||
p1 = subprocess.Popen(['which', 'ccx'], stdout=subprocess.PIPE)
|
p1 = subprocess.Popen(['which', 'ccx'], stdout=subprocess.PIPE)
|
||||||
if p1.wait() == 0:
|
if p1.wait() == 0:
|
||||||
if sys.version_info.major >= 3:
|
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:
|
else:
|
||||||
ccx_path = p1.stdout.read().split('\n')[0]
|
ccx_path = p1.stdout.read().split('\n')[0]
|
||||||
elif p1.wait() == 1:
|
elif p1.wait() == 1:
|
||||||
|
|||||||
+5
-3
@@ -22,11 +22,15 @@
|
|||||||
#* Milos Koutny 2010 *
|
#* Milos Koutny 2010 *
|
||||||
#***************************************************************************/
|
#***************************************************************************/
|
||||||
|
|
||||||
import FreeCAD, Part, os, FreeCADGui, __builtin__
|
import FreeCAD, Part, os, FreeCADGui
|
||||||
from FreeCAD import Base
|
from FreeCAD import Base
|
||||||
from math import *
|
from math import *
|
||||||
import ImportGui
|
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 #
|
# 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 #
|
# 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):
|
def open(filename):
|
||||||
"""called when freecad opens an Emn file"""
|
"""called when freecad opens an Emn file"""
|
||||||
docname = os.path.splitext(os.path.basename(filename))[0]
|
docname = os.path.splitext(os.path.basename(filename))[0]
|
||||||
|
|||||||
@@ -138,8 +138,15 @@ def cmdCreateImageScaling(name):
|
|||||||
def accept(self):
|
def accept(self):
|
||||||
sel = FreeCADGui.Selection.getSelection()
|
sel = FreeCADGui.Selection.getSelection()
|
||||||
try:
|
try:
|
||||||
locale=QtCore.QLocale.system()
|
try:
|
||||||
d, ok = locale.toFloat(str(eval(self.lineEdit.text())))
|
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:
|
if not ok:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
s=d/self.distance
|
s=d/self.distance
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
# * *
|
# * *
|
||||||
# ***************************************************************************
|
# ***************************************************************************
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
# here the usage description if you use this tool from the command line ("__main__")
|
# here the usage description if you use this tool from the command line ("__main__")
|
||||||
CommandlineUsage = """Material - Tool to work with FreeCAD Material definition cards
|
CommandlineUsage = """Material - Tool to work with FreeCAD Material definition cards
|
||||||
|
|
||||||
@@ -62,7 +64,10 @@ def importFCMat(fileName):
|
|||||||
|
|
||||||
Config = configparser.RawConfigParser()
|
Config = configparser.RawConfigParser()
|
||||||
Config.optionxform = str
|
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 = {}
|
dict1 = {}
|
||||||
for section in Config.sections():
|
for section in Config.sections():
|
||||||
options = Config.options(section)
|
options = Config.options(section)
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ except AttributeError:
|
|||||||
return QtGui.QApplication.translate(context, text, None)
|
return QtGui.QApplication.translate(context, text, None)
|
||||||
|
|
||||||
import io
|
import io
|
||||||
|
import sys
|
||||||
|
PY2 = sys.version_info.major == 2
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import FreeCAD
|
import FreeCAD
|
||||||
@@ -144,18 +146,23 @@ def callopenscad(inputfilename,outputfilename=None,outputext='csg',keepname=Fals
|
|||||||
import FreeCAD,os,subprocess,tempfile,time
|
import FreeCAD,os,subprocess,tempfile,time
|
||||||
def check_output2(*args,**kwargs):
|
def check_output2(*args,**kwargs):
|
||||||
kwargs.update({'stdout':subprocess.PIPE,'stderr':subprocess.PIPE})
|
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,stderrd = p.communicate()
|
||||||
stdoutd = stdoutd.decode("utf8")
|
if not PY2:
|
||||||
stderrd = stderrd.decode("utf8")
|
stdoutd = stdoutd.decode("utf8")
|
||||||
|
stderrd = stderrd.decode("utf8")
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise OpenSCADError('%s %s\n' % (stdoutd.strip(),stderrd.strip()))
|
raise OpenSCADError('%s %s\n' % (stdoutd.strip(),stderrd.strip()))
|
||||||
#raise Exception,'stdout %s\n stderr%s' %(stdoutd,stderrd)
|
#raise Exception,'stdout %s\n stderr%s' %(stdoutd,stderrd)
|
||||||
if stderrd.strip():
|
if not PY2:
|
||||||
FreeCAD.Console.PrintWarning(stderrd+u'\n')
|
if stderrd.strip():
|
||||||
if stdoutd.strip():
|
FreeCAD.Console.PrintWarning(stderrd+u'\n')
|
||||||
FreeCAD.Console.PrintMessage(stdoutd+u'\n')
|
if stdoutd.strip():
|
||||||
return stdoutd
|
FreeCAD.Console.PrintMessage(stdoutd+u'\n')
|
||||||
|
return stdoutd
|
||||||
|
|
||||||
osfilename = FreeCAD.ParamGet(\
|
osfilename = FreeCAD.ParamGet(\
|
||||||
"User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
|
"User parameter:BaseApp/Preferences/Mod/OpenSCAD").\
|
||||||
@@ -182,7 +189,10 @@ def callopenscadstring(scadstr,outputext='csg'):
|
|||||||
dir1=tempfile.gettempdir()
|
dir1=tempfile.gettempdir()
|
||||||
inputfilename=os.path.join(dir1,'%s.scad' % next(tempfilenamegen))
|
inputfilename=os.path.join(dir1,'%s.scad' % next(tempfilenamegen))
|
||||||
inputfile = io.open(inputfilename,'w', encoding="utf8")
|
inputfile = io.open(inputfilename,'w', encoding="utf8")
|
||||||
inputfile.write(scadstr)
|
if PY2:
|
||||||
|
inputfile.write(scadstr.decode('utf8'))
|
||||||
|
else:
|
||||||
|
inputfile.write(scadstr)
|
||||||
inputfile.close()
|
inputfile.close()
|
||||||
outputfilename = callopenscad(inputfilename,outputext=outputext,\
|
outputfilename = callopenscad(inputfilename,outputext=outputext,\
|
||||||
keepname=True)
|
keepname=True)
|
||||||
|
|||||||
@@ -66,21 +66,29 @@ App::DocumentObjectExecReturn *Compound::execute(void)
|
|||||||
TopoDS_Compound comp;
|
TopoDS_Compound comp;
|
||||||
builder.MakeCompound(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();
|
const std::vector<DocumentObject*>& links = Links.getValues();
|
||||||
for (std::vector<DocumentObject*>::const_iterator it = links.begin(); it != links.end(); ++it) {
|
for (std::vector<DocumentObject*>::const_iterator it = links.begin(); it != links.end(); ++it) {
|
||||||
if (*it && (*it)->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
if (*it && (*it)->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||||
Part::Feature* fea = static_cast<Part::Feature*>(*it);
|
Part::Feature* fea = static_cast<Part::Feature*>(*it);
|
||||||
const TopoDS_Shape& sh = fea->Shape.getValue();
|
|
||||||
if (!sh.IsNull()) {
|
auto pos = tempLinks.insert(fea);
|
||||||
builder.Add(comp, sh);
|
if (pos.second) {
|
||||||
TopTools_IndexedMapOfShape faceMap;
|
const TopoDS_Shape& sh = fea->Shape.getValue();
|
||||||
TopExp::MapShapes(sh, TopAbs_FACE, faceMap);
|
if (!sh.IsNull()) {
|
||||||
ShapeHistory hist;
|
builder.Add(comp, sh);
|
||||||
hist.type = TopAbs_FACE;
|
TopTools_IndexedMapOfShape faceMap;
|
||||||
for (int i=1; i<=faceMap.Extent(); i++) {
|
TopExp::MapShapes(sh, TopAbs_FACE, faceMap);
|
||||||
hist.shapeMap[i-1].push_back(countFaces++);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -908,11 +908,15 @@ void CmdPartCompound::activated(int iMsg)
|
|||||||
|
|
||||||
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
|
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
std::vector<std::string> tempSelNames;
|
|
||||||
|
// avoid duplicates without changing the order
|
||||||
|
std::set<std::string> tempSelNames;
|
||||||
str << "App.activeDocument()." << FeatName << ".Links = [";
|
str << "App.activeDocument()." << FeatName << ".Links = [";
|
||||||
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it){
|
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it) {
|
||||||
str << "App.activeDocument()." << it->FeatName << ",";
|
auto pos = tempSelNames.insert(it->FeatName);
|
||||||
tempSelNames.push_back(it->FeatName);
|
if (pos.second) {
|
||||||
|
str << "App.activeDocument()." << it->FeatName << ",";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
str << "]";
|
str << "]";
|
||||||
|
|
||||||
|
|||||||
@@ -383,8 +383,8 @@ void PartGui::DimensionLinear::setupDimension()
|
|||||||
|
|
||||||
//dimension arrows
|
//dimension arrows
|
||||||
float dimLength = (point2.getValue()-point1.getValue()).length();
|
float dimLength = (point2.getValue()-point1.getValue()).length();
|
||||||
float coneHeight = dimLength * .05;
|
float coneHeight = dimLength * 0.05;
|
||||||
float coneRadius = coneHeight / 2;
|
float coneRadius = coneHeight * 0.5;
|
||||||
|
|
||||||
SoCone *cone = new SoCone();
|
SoCone *cone = new SoCone();
|
||||||
cone->bottomRadius.setValue(coneRadius);
|
cone->bottomRadius.setValue(coneRadius);
|
||||||
@@ -392,8 +392,8 @@ void PartGui::DimensionLinear::setupDimension()
|
|||||||
|
|
||||||
char lStr[100];
|
char lStr[100];
|
||||||
char rStr[100];
|
char rStr[100];
|
||||||
snprintf(lStr, sizeof(lStr), "translation %.2f 0.0 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 -%.2f 0.0", coneHeight*0.5);
|
snprintf(rStr, sizeof(rStr), "translation 0.0 -%.6f 0.0", coneHeight * 0.5);
|
||||||
|
|
||||||
setPart("leftArrow.shape", cone);
|
setPart("leftArrow.shape", cone);
|
||||||
set("leftArrow.transform", "rotation 0.0 0.0 1.0 1.5707963");
|
set("leftArrow.transform", "rotation 0.0 0.0 1.0 1.5707963");
|
||||||
@@ -1072,7 +1072,7 @@ void PartGui::DimensionAngular::setupDimension()
|
|||||||
|
|
||||||
//dimension arrows
|
//dimension arrows
|
||||||
float coneHeight = radius.getValue() * 0.1;
|
float coneHeight = radius.getValue() * 0.1;
|
||||||
float coneRadius = coneHeight / 2;
|
float coneRadius = coneHeight * 0.5;
|
||||||
|
|
||||||
SoCone *cone = new SoCone();
|
SoCone *cone = new SoCone();
|
||||||
cone->bottomRadius.setValue(coneRadius);
|
cone->bottomRadius.setValue(coneRadius);
|
||||||
@@ -1080,8 +1080,8 @@ void PartGui::DimensionAngular::setupDimension()
|
|||||||
|
|
||||||
char str1[100];
|
char str1[100];
|
||||||
char str2[100];
|
char str2[100];
|
||||||
snprintf(str1, sizeof(str1), "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 -%.2f 0.0", coneHeight*0.5);
|
snprintf(str2, sizeof(str2), "translation 0.0 -%.6f 0.0", coneHeight * 0.5);
|
||||||
|
|
||||||
setPart("arrow1.shape", cone);
|
setPart("arrow1.shape", cone);
|
||||||
set("arrow1.localTransform", "rotation 0.0 0.0 1.0 3.1415927");
|
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();
|
(prop)->getValues();
|
||||||
Part::Compound* objComp = static_cast<Part::Compound*>(getObject());
|
Part::Compound* objComp = static_cast<Part::Compound*>(getObject());
|
||||||
std::vector<App::DocumentObject*> sources = objComp->Links.getValues();
|
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())
|
if (hist.size() != sources.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
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.
|
hide the actual features from Path and they can't be referenced directly.
|
||||||
'''
|
'''
|
||||||
ids = string.split(sub, '.')
|
ids = sub.split(".")
|
||||||
holeId = int(ids[0])
|
holeId = int(ids[0])
|
||||||
wireId = int(ids[1])
|
wireId = int(ids[1])
|
||||||
edgeId = int(ids[2])
|
edgeId = int(ids[2])
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ import PathScripts.PathOpGui as PathOpGui
|
|||||||
|
|
||||||
from PySide import QtCore, QtGui
|
from PySide import QtCore, QtGui
|
||||||
|
|
||||||
|
import sys
|
||||||
|
if sys.version_info.major >= 3:
|
||||||
|
xrange = range
|
||||||
|
|
||||||
__title__ = "Base for Circular Hole based operations' UI"
|
__title__ = "Base for Circular Hole based operations' UI"
|
||||||
__author__ = "sliptonic (Brad Collette)"
|
__author__ = "sliptonic (Brad Collette)"
|
||||||
__url__ = "http://www.freecadweb.org"
|
__url__ = "http://www.freecadweb.org"
|
||||||
|
|||||||
@@ -1019,6 +1019,10 @@ class TaskPanel:
|
|||||||
Draft.move(sel.Object, by)
|
Draft.move(sel.Object, by)
|
||||||
|
|
||||||
def updateSelection(self):
|
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()
|
sel = FreeCADGui.Selection.getSelectionEx()
|
||||||
|
|
||||||
if len(sel) == 1 and len(sel[0].SubObjects) == 1:
|
if len(sel) == 1 and len(sel[0].SubObjects) == 1:
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ import PathScripts.PathOp as PathOp
|
|||||||
|
|
||||||
from PySide import QtCore
|
from PySide import QtCore
|
||||||
|
|
||||||
|
import sys
|
||||||
|
if sys.version_info.major >= 3:
|
||||||
|
xrange = range
|
||||||
|
|
||||||
__title__ = "Path Surface Operation"
|
__title__ = "Path Surface Operation"
|
||||||
__author__ = "sliptonic (Brad Collette)"
|
__author__ = "sliptonic (Brad Collette)"
|
||||||
__url__ = "http://www.freecadweb.org"
|
__url__ = "http://www.freecadweb.org"
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ CURRENT_Z = 0
|
|||||||
|
|
||||||
|
|
||||||
# to distinguish python built-in open function from the one declared below
|
# to distinguish python built-in open function from the one declared below
|
||||||
if open.__module__ == '__builtin__':
|
if open.__module__ in ['__builtin__','io']:
|
||||||
pythonopen = open
|
pythonopen = open
|
||||||
|
|
||||||
|
|
||||||
@@ -393,7 +393,7 @@ def drill_translate(outstring, cmd, params):
|
|||||||
RETRACT_Z = CURRENT_Z
|
RETRACT_Z = CURRENT_Z
|
||||||
|
|
||||||
# Recupere les valeurs des autres parametres
|
# Recupere les valeurs des autres parametres
|
||||||
drill_Speed = params['F']
|
drill_Speed = params['F'] * SPEED_MULTIPLIER
|
||||||
if cmd == 'G83':
|
if cmd == 'G83':
|
||||||
drill_Step = params['Q']
|
drill_Step = params['Q']
|
||||||
elif cmd == 'G82':
|
elif cmd == 'G82':
|
||||||
|
|||||||
@@ -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){
|
for (std::vector<Part::Geometry *>::const_iterator it=svals.begin(); it != svals.end(); ++it){
|
||||||
Part::Geometry *geoNew = (*it)->copy();
|
Part::Geometry *geoNew = (*it)->copy();
|
||||||
if(construction) {
|
if(construction && geoNew->getTypeId() != Part::GeomPoint::getClassTypeId()) {
|
||||||
geoNew->Construction = true;
|
geoNew->Construction = true;
|
||||||
}
|
}
|
||||||
newVals.push_back(geoNew);
|
newVals.push_back(geoNew);
|
||||||
@@ -5174,11 +5174,13 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
|
|||||||
int sourceid = 0;
|
int sourceid = 0;
|
||||||
for (std::vector< Sketcher::Constraint * >::const_iterator it= scvals.begin(); it != scvals.end(); ++it,nextcid++,sourceid++) {
|
for (std::vector< Sketcher::Constraint * >::const_iterator it= scvals.begin(); it != scvals.end(); ++it,nextcid++,sourceid++) {
|
||||||
|
|
||||||
if ((*it)->Type == Sketcher::Distance ||
|
if ((*it)->Type == Sketcher::Distance ||
|
||||||
(*it)->Type == Sketcher::Radius ||
|
(*it)->Type == Sketcher::Radius ||
|
||||||
(*it)->Type == Sketcher::Diameter ||
|
(*it)->Type == Sketcher::Diameter ||
|
||||||
(*it)->Type == Sketcher::Angle ||
|
(*it)->Type == Sketcher::Angle ||
|
||||||
(*it)->Type == Sketcher::SnellsLaw) {
|
(*it)->Type == Sketcher::SnellsLaw ||
|
||||||
|
(*it)->Type == Sketcher::DistanceX ||
|
||||||
|
(*it)->Type == Sketcher::DistanceY ) {
|
||||||
// then we link its value to the parent
|
// 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)
|
// (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) {
|
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()));
|
boost::shared_ptr<App::Expression> expr(App::Expression::parse(this, spath.getDocumentObjectName().getString() +std::string(1,'.') + spath.toString()));
|
||||||
setExpression(Constraints.createPath(nextcid), expr);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1195,11 +1195,17 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case STATUS_SKETCH_UseRubberBand: {
|
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;
|
newCursorPos = cursorPos;
|
||||||
rubberband->setCoords(prvCursorPos.getValue()[0],
|
rubberband->setCoords(prvCursorPos.getValue()[0],
|
||||||
viewer->getGLWidget()->height() - prvCursorPos.getValue()[1],
|
viewer->getGLWidget()->height()*dpr - prvCursorPos.getValue()[1],
|
||||||
newCursorPos.getValue()[0],
|
newCursorPos.getValue()[0],
|
||||||
viewer->getGLWidget()->height() - newCursorPos.getValue()[1]);
|
viewer->getGLWidget()->height()*dpr - newCursorPos.getValue()[1]);
|
||||||
viewer->redraw();
|
viewer->redraw();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ known issues:
|
|||||||
import zipfile
|
import zipfile
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
import FreeCAD as App
|
import FreeCAD as App
|
||||||
|
import sys
|
||||||
|
|
||||||
try: import FreeCADGui
|
try: import FreeCADGui
|
||||||
except ValueError: gui = False
|
except ValueError: gui = False
|
||||||
@@ -371,7 +372,10 @@ def handleCells(cellList, actCellSheet, sList):
|
|||||||
if cellType == 'n':
|
if cellType == 'n':
|
||||||
actCellSheet.set(ref, theValue)
|
actCellSheet.set(ref, theValue)
|
||||||
if cellType == 's':
|
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):
|
def handleWorkBook(theBook, sheetDict, Doc):
|
||||||
|
|||||||
@@ -517,6 +517,7 @@ void QGIFace::buildSvgHatch()
|
|||||||
before.append(QString::fromStdString(SVGCOLPREFIX + SVGCOLDEFAULT));
|
before.append(QString::fromStdString(SVGCOLPREFIX + SVGCOLDEFAULT));
|
||||||
after.append(QString::fromStdString(SVGCOLPREFIX + m_svgCol));
|
after.append(QString::fromStdString(SVGCOLPREFIX + m_svgCol));
|
||||||
QByteArray colorXML = m_svgXML.replace(before,after);
|
QByteArray colorXML = m_svgXML.replace(before,after);
|
||||||
|
long int tileCount = 0;
|
||||||
for (int iw = 0; iw < int(nw); iw++) {
|
for (int iw = 0; iw < int(nw); iw++) {
|
||||||
for (int ih = 0; ih < int(nh); ih++) {
|
for (int ih = 0; ih < int(nh); ih++) {
|
||||||
QGCustomSvg* tile = new QGCustomSvg();
|
QGCustomSvg* tile = new QGCustomSvg();
|
||||||
@@ -525,6 +526,14 @@ void QGIFace::buildSvgHatch()
|
|||||||
tile->setParentItem(m_rect);
|
tile->setParentItem(m_rect);
|
||||||
tile->setPos(iw*wTile,-h + ih*hTile);
|
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");
|
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/PAT");
|
||||||
|
|
||||||
m_maxSeg = hGrp->GetInt("MaxSeg",10000l);
|
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;
|
std::vector<DashSpec> m_dashSpecs;
|
||||||
long int m_segCount;
|
long int m_segCount;
|
||||||
long int m_maxSeg;
|
long int m_maxSeg;
|
||||||
|
long int m_maxTile;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -374,7 +374,10 @@ void QGIViewPart::drawViewPart()
|
|||||||
}
|
}
|
||||||
newFace->isHatched(true);
|
newFace->isHatched(true);
|
||||||
newFace->setFillMode(QGIFace::GeomHatchFill);
|
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());
|
newFace->setHatchFile(fGeom->FilePattern.getValue());
|
||||||
Gui::ViewProvider* gvp = QGIView::getViewProvider(fGeom);
|
Gui::ViewProvider* gvp = QGIView::getViewProvider(fGeom);
|
||||||
ViewProviderGeomHatch* geomVp = dynamic_cast<ViewProviderGeomHatch*>(gvp);
|
ViewProviderGeomHatch* geomVp = dynamic_cast<ViewProviderGeomHatch*>(gvp);
|
||||||
@@ -392,7 +395,10 @@ void QGIViewPart::drawViewPart()
|
|||||||
Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch);
|
Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch);
|
||||||
ViewProviderHatch* hatchVp = dynamic_cast<ViewProviderHatch*>(gvp);
|
ViewProviderHatch* hatchVp = dynamic_cast<ViewProviderHatch*>(gvp);
|
||||||
if (hatchVp != nullptr) {
|
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());
|
newFace->setHatchColor(hatchVp->HatchColor.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -541,7 +547,8 @@ void QGIViewPart::removePrimitives()
|
|||||||
for (auto& c:children) {
|
for (auto& c:children) {
|
||||||
QGIPrimPath* prim = dynamic_cast<QGIPrimPath*>(c);
|
QGIPrimPath* prim = dynamic_cast<QGIPrimPath*>(c);
|
||||||
if (prim) {
|
if (prim) {
|
||||||
removeFromGroup(prim);
|
prim->hide();
|
||||||
|
// removeFromGroup(prim);
|
||||||
scene()->removeItem(prim);
|
scene()->removeItem(prim);
|
||||||
delete prim;
|
delete prim;
|
||||||
}
|
}
|
||||||
@@ -559,11 +566,13 @@ void QGIViewPart::removeDecorations()
|
|||||||
QGIDecoration* decor = dynamic_cast<QGIDecoration*>(c);
|
QGIDecoration* decor = dynamic_cast<QGIDecoration*>(c);
|
||||||
QGIMatting* mat = dynamic_cast<QGIMatting*>(c);
|
QGIMatting* mat = dynamic_cast<QGIMatting*>(c);
|
||||||
if (decor) {
|
if (decor) {
|
||||||
removeFromGroup(decor);
|
decor->hide();
|
||||||
|
// removeFromGroup(decor);
|
||||||
scene()->removeItem(decor);
|
scene()->removeItem(decor);
|
||||||
delete decor;
|
delete decor;
|
||||||
} else if (mat) {
|
} else if (mat) {
|
||||||
removeFromGroup(mat);
|
mat->hide();
|
||||||
|
// removeFromGroup(mat);
|
||||||
scene()->removeItem(mat);
|
scene()->removeItem(mat);
|
||||||
delete mat;
|
delete mat;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,8 +47,13 @@
|
|||||||
|
|
||||||
using namespace TechDrawGui;
|
using namespace TechDrawGui;
|
||||||
|
|
||||||
App::PropertyFloatConstraint::Constraints ViewProviderHatch::scaleRange = {Precision::Confusion(),
|
//scaleRange = {lowerLimit, upperLimit, stepSize}
|
||||||
std::numeric_limits<double>::max(),
|
//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())};
|
pow(10,- Base::UnitsApi::getDecimals())};
|
||||||
|
|
||||||
|
|
||||||
@@ -99,9 +104,11 @@ void ViewProviderHatch::onChanged(const App::Property* prop)
|
|||||||
{
|
{
|
||||||
if ((prop == &HatchScale) ||
|
if ((prop == &HatchScale) ||
|
||||||
(prop == &HatchColor)) {
|
(prop == &HatchColor)) {
|
||||||
TechDraw::DrawViewPart* parent = getViewObject()->getSourceView();
|
if (HatchScale.getValue() > 0.0) {
|
||||||
if (parent) {
|
TechDraw::DrawViewPart* parent = getViewObject()->getSourceView();
|
||||||
parent->requestPaint();
|
if (parent) {
|
||||||
|
parent->requestPaint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,6 +227,11 @@ BrowserView::BrowserView(QWidget* parent)
|
|||||||
isLoading(false),
|
isLoading(false),
|
||||||
textSizeMultiplier(1.0)
|
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);
|
view = new WebView(this);
|
||||||
setCentralWidget(view);
|
setCentralWidget(view);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,36 @@
|
|||||||
install(FILES org.freecadweb.FreeCAD.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo)
|
include(GNUInstallDirs)
|
||||||
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)
|
if(NOT DEFINED APPDATA_RELEASE_DATE)
|
||||||
install(FILES org.freecadweb.FreeCAD.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mime/packages)
|
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="help">https://forum.freecadweb.org</url>
|
||||||
<url type="donation">https://www.freecadweb.org/wiki/Donate</url>
|
<url type="donation">https://www.freecadweb.org/wiki/Donate</url>
|
||||||
<update_contact>yorik_AT_uncreated.net</update_contact>
|
<update_contact>yorik_AT_uncreated.net</update_contact>
|
||||||
<content_rating type="oars-1.1" />
|
<content_rating type="oars-1.1"/>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="0.17" date="2018-04-06"></release>
|
<release version="@PACKAGE_VERSION@" date="@APPDATA_RELEASE_DATE@"/>
|
||||||
</releases>
|
</releases>
|
||||||
</component>
|
</component>
|
||||||
Reference in New Issue
Block a user