From 41ae2518dc0ca6fa391436748f7a59d10bca8710 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Fri, 14 Feb 2020 20:35:42 -0500 Subject: [PATCH 1/6] [Part]Handle CJK font names for ShapeString --- src/Mod/Part/App/AppPartPy.cpp | 15 +++++++++++++++ src/Mod/Part/App/FT2FC.cpp | 24 +++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp index ac8ca05e82..748735779c 100644 --- a/src/Mod/Part/App/AppPartPy.cpp +++ b/src/Mod/Part/App/AppPartPy.cpp @@ -89,6 +89,9 @@ # include #endif +#include +#include + #include #include @@ -1802,7 +1805,19 @@ private: try { if (useFontSpec) { +#ifdef FC_OS_WIN32 +// Windows doesn't do Utf8 by default and FreeType doesn't do wchar. +// this is a hacky work around. +// copy fontspec to Ascii temp name + std::string tempFile = Base::FileInfo::getTempFileName(); //utf8/ascii + Base::FileInfo fiIn(fontspec); + fiIn.copyTo(tempFile.c_str()); + CharList = FT2FC(unichars,pysize,tempFile.c_str(),height,track); + Base::FileInfo fiTemp(tempFile); + fiTemp.deleteFile(); +#else CharList = FT2FC(unichars,pysize,fontspec,height,track); +#endif } else { CharList = FT2FC(unichars,pysize,dir,fontfile,height,track); diff --git a/src/Mod/Part/App/FT2FC.cpp b/src/Mod/Part/App/FT2FC.cpp index 830d61be4c..c8e9a4bd11 100644 --- a/src/Mod/Part/App/FT2FC.cpp +++ b/src/Mod/Part/App/FT2FC.cpp @@ -120,13 +120,23 @@ PyObject* FT2FC(const Py_UNICODE *PyUString, throw std::runtime_error(ErrorMsg.str()); } - // FT does not return an error if font file not found? - std::ifstream is; - is.open (FontSpec); - if (!is) { - ErrorMsg << "Font file not found: " << FontSpec; - throw std::runtime_error(ErrorMsg.str()); - } + +#ifdef FC_OS_WIN32 + Base::FileInfo fi(FontSpec); + if (!fi.isReadable()) { + ErrorMsg << "Font file not found (Win): " << FontSpec; + throw std::runtime_error(ErrorMsg.str()); + } +#else + // FT does not return an error if font file not found? + std::ifstream is; + is.open (FontSpec); + if (!is) { + ErrorMsg << "Font file not found: " << FontSpec; + throw std::runtime_error(ErrorMsg.str()); + } +#endif + error = FT_New_Face(FTLib,FontSpec,FaceIndex, &FTFont); if(error) { From 454fe91c3c4573b3a4139d984c742eeba968af68 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 19 Feb 2020 19:58:34 +0100 Subject: [PATCH 2/6] App/Gui: implement a lightweight weak_ptr like class to work with Document, DocumentObject and ViewProvider --- src/App/DocumentObserver.cpp | 133 +++++++++++++++++++++++++++++++++++ src/App/DocumentObserver.h | 79 ++++++++++++++++++++- src/Gui/DocumentObserver.cpp | 131 ++++++++++++++++++++++++++++++++++ src/Gui/DocumentObserver.h | 76 ++++++++++++++++++++ 4 files changed, 418 insertions(+), 1 deletion(-) diff --git a/src/App/DocumentObserver.cpp b/src/App/DocumentObserver.cpp index c88043d628..e6650d5060 100644 --- a/src/App/DocumentObserver.cpp +++ b/src/App/DocumentObserver.cpp @@ -257,6 +257,7 @@ Property *DocumentObjectT::getProperty() const { return obj->getPropertyByName(property.c_str()); return 0; } + // ----------------------------------------------------------------------------- SubObjectT::SubObjectT() @@ -387,6 +388,138 @@ std::vector SubObjectT::getSubObjectList() const { } // ----------------------------------------------------------------------------- + +class DocumentWeakPtrT::Private { +public: + Private(App::Document* doc) : _document(doc) { + if (doc) { + connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind + (&Private::deletedDocument, this, _1)); + } + } + + void deletedDocument(const App::Document& doc) { + if (_document == &doc) + reset(); + } + void reset() { + connectApplicationDeletedDocument.disconnect(); + _document = nullptr; + } + + App::Document* _document; + typedef boost::signals2::scoped_connection Connection; + Connection connectApplicationDeletedDocument; +}; + +DocumentWeakPtrT::DocumentWeakPtrT(App::Document* doc) noexcept + : d(new Private(doc)) +{ +} + +DocumentWeakPtrT::~DocumentWeakPtrT() +{ +} + +void DocumentWeakPtrT::reset() noexcept +{ + d->reset(); +} + +bool DocumentWeakPtrT::expired() const noexcept +{ + return (d->_document == nullptr); +} + +App::Document* DocumentWeakPtrT::operator->() noexcept +{ + return d->_document; +} + +// ----------------------------------------------------------------------------- + +class DocumentObjectWeakPtrT::Private { +public: + Private(App::DocumentObject* obj) : object(obj), indocument(false) { + if (obj) { + indocument = true; + connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(boost::bind + (&Private::deletedDocument, this, _1)); + App::Document* doc = obj->getDocument(); + connectDocumentCreatedObject = doc->signalNewObject.connect(boost::bind + (&Private::createdObject, this, _1)); + connectDocumentDeletedObject = doc->signalDeletedObject.connect(boost::bind + (&Private::deletedObject, this, _1)); + } + } + void deletedDocument(const App::Document& doc) { + // When deleting document then there is no way to undo it + if (object && object->getDocument() == &doc) { + reset(); + } + } + void createdObject(const App::DocumentObject& obj) { + // When undoing the removal + if (object == &obj) { + indocument = true; + } + } + void deletedObject(const App::DocumentObject& obj) { + if (object == &obj) { + indocument = false; + } + } + void reset() { + connectApplicationDeletedDocument.disconnect(); + connectDocumentCreatedObject.disconnect(); + connectDocumentDeletedObject.disconnect(); + object = nullptr; + indocument = false; + } + App::DocumentObject* get() const { + return indocument ? object : nullptr; + } + + App::DocumentObject* object; + bool indocument; + typedef boost::signals2::scoped_connection Connection; + Connection connectApplicationDeletedDocument; + Connection connectDocumentCreatedObject; + Connection connectDocumentDeletedObject; +}; + +DocumentObjectWeakPtrT::DocumentObjectWeakPtrT(App::DocumentObject* obj) noexcept + : d(new Private(obj)) +{ +} + +DocumentObjectWeakPtrT::~DocumentObjectWeakPtrT() +{ + +} + +App::DocumentObject* DocumentObjectWeakPtrT::_get() const noexcept +{ + return d->get(); +} + +void DocumentObjectWeakPtrT::reset() noexcept +{ + d->reset(); +} + +bool DocumentObjectWeakPtrT::expired() const noexcept +{ + return !d->indocument; +} + +App::DocumentObject* DocumentObjectWeakPtrT::operator->() noexcept +{ + return d->get(); +} + +// ----------------------------------------------------------------------------- + DocumentObserver::DocumentObserver() : _document(0) { this->connectApplicationCreatedDocument = App::GetApplication().signalNewDocument.connect(boost::bind diff --git a/src/App/DocumentObserver.h b/src/App/DocumentObserver.h index dcf7936304..eae3295755 100644 --- a/src/App/DocumentObserver.h +++ b/src/App/DocumentObserver.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace App { @@ -144,7 +145,7 @@ private: std::string property; }; -class AppExport SubObjectT: public DocumentObjectT +class AppExport SubObjectT : public DocumentObjectT { public: /*! Constructor */ @@ -205,6 +206,82 @@ private: std::string subname; }; +/** + * @brief The DocumentWeakPtrT class + */ +class AppExport DocumentWeakPtrT +{ +public: + DocumentWeakPtrT(App::Document*) noexcept; + ~DocumentWeakPtrT(); + + /*! + * \brief reset + * Releases the reference to the managed object. After the call *this manages no object. + */ + void reset() noexcept; + /*! + * \brief expired + * \return true if the managed object has already been deleted, false otherwise. + */ + bool expired() const noexcept; + /*! + * \brief operator -> + * \return pointer to the document + */ + App::Document* operator->() noexcept; + +private: + // disable + DocumentWeakPtrT(const DocumentWeakPtrT&); + DocumentWeakPtrT& operator=(const DocumentWeakPtrT&); + + class Private; + std::unique_ptr d; +}; + +/** + * @brief The DocumentObjectWeakPtrT class + */ +class AppExport DocumentObjectWeakPtrT +{ +public: + DocumentObjectWeakPtrT(App::DocumentObject*) noexcept; + ~DocumentObjectWeakPtrT(); + + /*! + * \brief reset + * Releases the reference to the managed object. After the call *this manages no object. + */ + void reset() noexcept; + /*! + * \brief expired + * \return true if the managed object has already been deleted, false otherwise. + */ + bool expired() const noexcept; + /*! + * \brief operator -> + * \return pointer to the document + */ + App::DocumentObject* operator->() noexcept; + /*! Get a pointer to the object or 0 if it doesn't exist any more or the type doesn't match. */ + template + inline T* get() const noexcept + { + return Base::freecad_dynamic_cast(_get()); + } + +private: + App::DocumentObject* _get() const noexcept; + // disable + DocumentObjectWeakPtrT(const DocumentObjectWeakPtrT&); + DocumentObjectWeakPtrT& operator=(const DocumentObjectWeakPtrT&); + +private: + class Private; + std::unique_ptr d; +}; + /** * The DocumentObserver class simplfies the step to write classes that listen * to what happens inside a document. diff --git a/src/Gui/DocumentObserver.cpp b/src/Gui/DocumentObserver.cpp index 7de3ccf928..2267c5dc95 100644 --- a/src/Gui/DocumentObserver.cpp +++ b/src/Gui/DocumentObserver.cpp @@ -199,6 +199,137 @@ std::string ViewProviderT::getObjectPython() const // ----------------------------------------------------------------------------- +class DocumentWeakPtrT::Private { +public: + Private(Gui::Document* doc) : _document(doc) { + if (doc) { + connectApplicationDeletedDocument = doc->signalDeleteDocument.connect(boost::bind + (&Private::deletedDocument, this, _1)); + } + } + + void deletedDocument(const Gui::Document& doc) { + if (_document == &doc) + reset(); + } + void reset() { + connectApplicationDeletedDocument.disconnect(); + _document = nullptr; + } + + Gui::Document* _document; + typedef boost::signals2::scoped_connection Connection; + Connection connectApplicationDeletedDocument; +}; + +DocumentWeakPtrT::DocumentWeakPtrT(Gui::Document* doc) noexcept + : d(new Private(doc)) +{ +} + +DocumentWeakPtrT::~DocumentWeakPtrT() +{ +} + +void DocumentWeakPtrT::reset() noexcept +{ + d->reset(); +} + +bool DocumentWeakPtrT::expired() const noexcept +{ + return (d->_document == nullptr); +} + +Gui::Document* DocumentWeakPtrT::operator->() noexcept +{ + return d->_document; +} + +// ----------------------------------------------------------------------------- + +class ViewProviderWeakPtrT::Private { +public: + Private(ViewProviderDocumentObject* obj) : object(obj), indocument(false) { + if (obj) { + indocument = true; + Gui::Document* doc = obj->getDocument(); + connectApplicationDeletedDocument = doc->signalDeleteDocument.connect(boost::bind + (&Private::deletedDocument, this, _1)); + connectDocumentCreatedObject = doc->signalNewObject.connect(boost::bind + (&Private::createdObject, this, _1)); + connectDocumentDeletedObject = doc->signalDeletedObject.connect(boost::bind + (&Private::deletedObject, this, _1)); + } + } + void deletedDocument(const Gui::Document& doc) { + // When deleting document then there is no way to undo it + if (object && object->getDocument() == &doc) { + reset(); + } + } + void createdObject(const Gui::ViewProvider& obj) { + // When undoing the removal + if (object == &obj) { + indocument = true; + } + } + void deletedObject(const Gui::ViewProvider& obj) { + if (object == &obj) { + indocument = false; + } + } + void reset() { + connectApplicationDeletedDocument.disconnect(); + connectDocumentCreatedObject.disconnect(); + connectDocumentDeletedObject.disconnect(); + object = nullptr; + indocument = false; + } + ViewProviderDocumentObject* get() const { + return indocument ? object : nullptr; + } + + Gui::ViewProviderDocumentObject* object; + bool indocument; + typedef boost::signals2::scoped_connection Connection; + Connection connectApplicationDeletedDocument; + Connection connectDocumentCreatedObject; + Connection connectDocumentDeletedObject; +}; + +ViewProviderWeakPtrT::ViewProviderWeakPtrT(ViewProviderDocumentObject* obj) noexcept + : d(new Private(obj)) +{ +} + +ViewProviderWeakPtrT::~ViewProviderWeakPtrT() +{ + +} + +ViewProviderDocumentObject* ViewProviderWeakPtrT::_get() const noexcept +{ + return d->get(); +} + +void ViewProviderWeakPtrT::reset() noexcept +{ + d->reset(); +} + +bool ViewProviderWeakPtrT::expired() const noexcept +{ + return !d->indocument; +} + +ViewProviderDocumentObject* ViewProviderWeakPtrT::operator->() noexcept +{ + return d->get(); +} + +// ----------------------------------------------------------------------------- + DocumentObserver::DocumentObserver() { } diff --git a/src/Gui/DocumentObserver.h b/src/Gui/DocumentObserver.h index 9f62ed4532..c25d8841dc 100644 --- a/src/Gui/DocumentObserver.h +++ b/src/Gui/DocumentObserver.h @@ -118,6 +118,82 @@ private: std::string object; }; +/** + * @brief The DocumentWeakPtrT class + */ +class GuiExport DocumentWeakPtrT +{ +public: + DocumentWeakPtrT(Gui::Document*) noexcept; + ~DocumentWeakPtrT(); + + /*! + * \brief reset + * Releases the reference to the managed object. After the call *this manages no object. + */ + void reset() noexcept; + /*! + * \brief expired + * \return true if the managed object has already been deleted, false otherwise. + */ + bool expired() const noexcept; + /*! + * \brief operator -> + * \return pointer to the document + */ + Gui::Document* operator->() noexcept; + +private: + // disable + DocumentWeakPtrT(const DocumentWeakPtrT&); + DocumentWeakPtrT& operator=(const DocumentWeakPtrT&); + + class Private; + std::unique_ptr d; +}; + +/** + * @brief The ViewProviderWeakPtrT class + */ +class AppExport ViewProviderWeakPtrT +{ +public: + ViewProviderWeakPtrT(ViewProviderDocumentObject*) noexcept; + ~ViewProviderWeakPtrT(); + + /*! + * \brief reset + * Releases the reference to the managed object. After the call *this manages no object. + */ + void reset() noexcept; + /*! + * \brief expired + * \return true if the managed object has already been deleted, false otherwise. + */ + bool expired() const noexcept; + /*! + * \brief operator -> + * \return pointer to the document + */ + ViewProviderDocumentObject* operator->() noexcept; + /*! Get a pointer to the object or 0 if it doesn't exist any more or the type doesn't match. */ + template + inline T* get() const noexcept + { + return Base::freecad_dynamic_cast(_get()); + } + +private: + ViewProviderDocumentObject* _get() const noexcept; + // disable + ViewProviderWeakPtrT(const ViewProviderWeakPtrT&); + ViewProviderWeakPtrT& operator=(const ViewProviderWeakPtrT&); + +private: + class Private; + std::unique_ptr d; +}; + /** * The DocumentObserver class simplifies the step to write classes that listen * to what happens inside a document. From 6ced131b6d90a90c89619c37f14a39c0e5c8266d Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Thu, 20 Feb 2020 05:46:26 +0100 Subject: [PATCH 3/6] FEM: result obj, pep8 --- src/Mod/Fem/femobjects/_FemResultMechanical.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Fem/femobjects/_FemResultMechanical.py b/src/Mod/Fem/femobjects/_FemResultMechanical.py index 192a39dad6..ddfbc3b36d 100644 --- a/src/Mod/Fem/femobjects/_FemResultMechanical.py +++ b/src/Mod/Fem/femobjects/_FemResultMechanical.py @@ -320,7 +320,7 @@ class _FemResultMechanical(): if len(obj.Stats) == 39: temp = obj.Stats for i in range(12, -1, -1): - del temp [3 * i + 1] + del temp[3 * i + 1] obj.Stats = temp def __getstate__(self): From 69378940b9233986ea2d64dcedfa8e270f1c1050 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Thu, 20 Feb 2020 08:00:15 +0100 Subject: [PATCH 4/6] FEM: result task panel, pep8 --- src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py b/src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py index 0ca622eb31..af30ba08d2 100644 --- a/src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py +++ b/src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py @@ -445,7 +445,8 @@ class _TaskPanelFemResultShow: if len(plt.get_fignums()) > 0: plt.show() else: - QtGui.QMessageBox.information(None, + QtGui.QMessageBox.information( + None, self.result_obj.Label + " - Information", "No histogram available.\nPlease select a result type first." ) From 0f8c763c472f417fa89c916dd9d1c78bc61ed7f3 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Thu, 20 Feb 2020 08:19:05 +0100 Subject: [PATCH 5/6] FEM: result task panel use single quotes instead of double ones --- .../femguiobjects/_ViewProviderFemResultMechanical.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py b/src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py index af30ba08d2..ee1d88b0ed 100644 --- a/src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py +++ b/src/Mod/Fem/femguiobjects/_ViewProviderFemResultMechanical.py @@ -519,11 +519,11 @@ class _TaskPanelFemResultShow: from ply import yacc import femtools.tokrules as tokrules identifiers = [ - 'x', 'y', 'z', 'T', 'vM', 'Peeq', 'P1', 'P2', 'P3', - 'sxx', 'syy', 'szz', 'sxy', 'sxz', 'syz', - 'exx', 'eyy', 'ezz', 'exy', 'exz', 'eyz', - 'MF', 'NP', 'rx', 'ry', 'rz', 'mc', - 's1x', 's1y', 's1z', 's2x', 's2y', 's2z', 's3x', 's3y', 's3z' + "x", "y", "z", "T", "vM", "Peeq", "P1", "P2", "P3", + "sxx", "syy", "szz", "sxy", "sxz", "syz", + "exx", "eyy", "ezz", "exy", "exz", "eyz", + "MF", "NP", "rx", "ry", "rz", "mc", + "s1x", "s1y", "s1z", "s2x", "s2y", "s2z", "s3x", "s3y", "s3z" ] tokrules.names = {} for i in identifiers: From 2f58af7af64702d48ebea36d5772da1af630cb08 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Wed, 19 Feb 2020 11:53:18 -0500 Subject: [PATCH 6/6] [TD]fix application of SectionLine preference --- src/Mod/TechDraw/Gui/DlgPrefsTechDraw3.ui | 19 +++++++++++-------- src/Mod/TechDraw/Gui/QGISectionLine.cpp | 21 ++++++++++++--------- src/Mod/TechDraw/Gui/QGISectionLine.h | 2 +- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/Mod/TechDraw/Gui/DlgPrefsTechDraw3.ui b/src/Mod/TechDraw/Gui/DlgPrefsTechDraw3.ui index f186f06fb1..3c83058c5b 100644 --- a/src/Mod/TechDraw/Gui/DlgPrefsTechDraw3.ui +++ b/src/Mod/TechDraw/Gui/DlgPrefsTechDraw3.ui @@ -284,7 +284,7 @@ - + 0 @@ -294,7 +294,7 @@ Dimension font size - + 4.000000000000000 @@ -306,7 +306,7 @@ - + 0 @@ -316,7 +316,7 @@ Dimension arrowhead size - + 5.000000000000000 @@ -821,20 +821,23 @@ 0 + + 1 + - SectionLineStyle + SectionLineStandard - Mod/TechDraw/General + Mod/TechDraw/Standards - ISO + ANSI - ANSI + ISO diff --git a/src/Mod/TechDraw/Gui/QGISectionLine.cpp b/src/Mod/TechDraw/Gui/QGISectionLine.cpp index 65b8750a67..7cff57aa7d 100644 --- a/src/Mod/TechDraw/Gui/QGISectionLine.cpp +++ b/src/Mod/TechDraw/Gui/QGISectionLine.cpp @@ -39,6 +39,9 @@ #include "QGIView.h" #include "QGISectionLine.h" +#define ANSISTANDARD 0 +#define ISOSTANDARD 1 + using namespace TechDrawGui; using namespace TechDraw; @@ -82,8 +85,8 @@ void QGISectionLine::makeLine() QPointF beginExtLine1,beginExtLine2; //ext line start pts for measure Start side and measure End side QPointF endExtLine1, endExtLine2; QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y); - int format = getPrefSectionFormat(); - if (format == 0) { //"ASME" + int format = getPrefSectionStandard(); + if (format == ANSISTANDARD) { //"ASME"/"ANSI" //draw from section line endpoint QPointF offsetBegin = m_extLen * offsetDir; beginExtLine1 = m_start; //from @@ -115,8 +118,8 @@ void QGISectionLine::makeLine() void QGISectionLine::makeArrows() { - int format = getPrefSectionFormat(); - if (format == 0) { + int format = getPrefSectionStandard(); + if (format == ANSISTANDARD) { makeArrowsTrad(); } else { makeArrowsISO(); @@ -180,8 +183,8 @@ void QGISectionLine::makeArrowsTrad() void QGISectionLine::makeSymbols() { - int format = getPrefSectionFormat(); - if (format == 0) { + int format = getPrefSectionStandard(); + if (format == ANSISTANDARD) { makeSymbolsTrad(); } else { makeSymbolsISO(); @@ -291,11 +294,11 @@ Qt::PenStyle QGISectionLine::getSectionStyle() } //ASME("traditional") vs ISO("reference arrow method") arrows -int QGISectionLine::getPrefSectionFormat() +int QGISectionLine::getPrefSectionStandard() { Base::Reference hGrp = App::GetApplication().GetUserParameter(). - GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Format"); - int format = hGrp->GetInt("SectionFormat", 0); + GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Standards"); + int format = hGrp->GetInt("SectionLineStandard", ISOSTANDARD); return format; } diff --git a/src/Mod/TechDraw/Gui/QGISectionLine.h b/src/Mod/TechDraw/Gui/QGISectionLine.h index a174bb3c62..2858505843 100644 --- a/src/Mod/TechDraw/Gui/QGISectionLine.h +++ b/src/Mod/TechDraw/Gui/QGISectionLine.h @@ -67,7 +67,7 @@ protected: void makeSymbolsTrad(); void makeSymbolsISO(); void setTools(); - int getPrefSectionFormat(); + int getPrefSectionStandard(); private: char* m_symbol;