diff --git a/src/Gui/Document.cpp b/src/Gui/Document.cpp index 324b1c6b7b..ed84eb045b 100644 --- a/src/Gui/Document.cpp +++ b/src/Gui/Document.cpp @@ -1775,7 +1775,6 @@ MDIView *Document::createView(const Base::Type& typeId) view3D->setWindowModified(this->isModified()); view3D->setWindowIcon(QApplication::windowIcon()); view3D->resize(400, 300); - view3D->getViewer()->redraw(); if (!cameraSettings.empty()) { const char *ppReturn = nullptr; @@ -1783,6 +1782,7 @@ MDIView *Document::createView(const Base::Type& typeId) } getMainWindow()->addWindow(view3D); + view3D->getViewer()->redraw(); return view3D; } return nullptr; diff --git a/src/Mod/Draft/Resources/ui/preferences-dxf.ui b/src/Mod/Draft/Resources/ui/preferences-dxf.ui index 45847555b4..ef408b3c10 100644 --- a/src/Mod/Draft/Resources/ui/preferences-dxf.ui +++ b/src/Mod/Draft/Resources/ui/preferences-dxf.ui @@ -584,11 +584,11 @@ If it is set to '0' the whole spline is treated as a straight segment. - Drawing Views will be exported as blocks. + TechDraw Views will be exported as blocks. This might fail for post DXF R12 templates. - Export Drawing Views as blocks + Export TechDraw Views as blocks true diff --git a/src/Mod/Draft/draftfunctions/dxf.py b/src/Mod/Draft/draftfunctions/dxf.py index 5464fa4d34..c5ec52ae69 100644 --- a/src/Mod/Draft/draftfunctions/dxf.py +++ b/src/Mod/Draft/draftfunctions/dxf.py @@ -67,8 +67,7 @@ def get_dxf(obj, direction=None): """ plane = None result = "" - if (obj.isDerivedFrom("Drawing::View") - or obj.isDerivedFrom("TechDraw::DrawView")): + if obj.isDerivedFrom("TechDraw::DrawView"): if obj.Source.isDerivedFrom("App::DocumentObjectGroup"): for o in obj.Source.Group: result += get_dxf(o, obj.Direction) diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py index 12972bde62..636d4710a6 100644 --- a/src/Mod/Draft/importDXF.py +++ b/src/Mod/Draft/importDXF.py @@ -3474,9 +3474,8 @@ def export(objectslist, filename, nospline=False, lwPoly=False): it will use its `getDXF()` method to provide the DXF information to write into `filename`. - If the list only contains a `'Drawing::FeaturePage'` - or a `'TechDraw::DrawPage'` object it will use `exportPage()` - to produce the DXF file. + If the list only contains a `'TechDraw::DrawPage'` object it will use + `exportPage()` to produce the DXF file. filename : str The path of the new DXF file. @@ -3544,10 +3543,6 @@ def export(objectslist, filename, nospline=False, lwPoly=False): f.write(dxf) f.close() - elif (len(exportList) == 1) and (exportList[0].isDerivedFrom("Drawing::FeaturePage")): - # page: special hack-export! (see below) - exportPage(exportList[0], filename) - elif (len(exportList) == 1) and (exportList[0].isDerivedFrom("TechDraw::DrawPage")): # page: special hack-export! (see below) exportPage(exportList[0], filename) @@ -3818,8 +3813,8 @@ def exportPage(page, filename): Parameters ---------- - page : object derived from 'Drawing::FeaturePage' or 'TechDraw::DrawPage' - A Drawing or TechDraw page to export. + page : object derived from 'TechDraw::DrawPage' + A TechDraw page to export. filename : str The path of the new DXF file. @@ -3897,9 +3892,8 @@ def getViewBlock(geom, view, blockcount): the `getDXF()` method of the `view`. view : page view - A Drawing or TechDraw view which may be of different types + A TechDraw view which may be of different types depending on the objects being projected: - ``'Drawing::FeatureViewPython'`, `'TechDraw::DrawViewDraft'`, or `'TechDraw::DrawViewArch'`. blockcount : int @@ -3937,7 +3931,7 @@ def getViewBlock(geom, view, blockcount): block += "0\nENDBLK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockEnd\n" insert += "0\nINSERT\n5\n_handle_\n8\n0\n6\nBYLAYER\n62\n256\n2\n" insert += view.Name + str(blockcount) - insert += "\n10\n" + str(view.X) + "\n20\n" + str(-view.Y) + insert += "\n10\n" + str(view.X) + "\n20\n" + str(view.Y) insert += "\n30\n0\n41\n" + str(view.Scale) + "\n42\n" + str(view.Scale) + "\n43\n" + str(view.Scale) insert += "\n50\n" + str(r) + "\n" blockcount += 1 @@ -3948,8 +3942,8 @@ def getViewBlock(geom, view, blockcount): return block, insert, blockcount -def getViewDXF(view, blocks=True): - """Return a DXF fragment from a Drawing view. +def getViewDXF(view): + """Return a DXF fragment from a TechDraw view. Depending on the type of page view, it will try obtaining `geom`, the DXF representation of `view`, @@ -3957,12 +3951,7 @@ def getViewDXF(view, blocks=True): with `getViewBlock(geom, view, blockcount)`, starting with a `blockcount` of 1. - If `view` is a group (`'App::DocumentObjectGroup'`) - it will recursively call itself in a loop `getViewDXF(child)`, - where `child` is a view contained in `view.Group`, - until all children are processed. - - If the `view` is `'Drawing::FeatureViewPart'`, + If the `view` is `'TechDraw::DrawViewPart'`, and if the global variable `dxfExportBlocks` exists, it will create the appropriate strings for `BLOCK` and `INSERT` sections, and increment the `blockcount`. @@ -3972,14 +3961,10 @@ def getViewDXF(view, blocks=True): Parameters ---------- view : App::DocumentObjectGroup or page view - A Drawing or TechDraw view which may be of different types + A TechDraw view which may be of different types depending on the objects being projected: - `'Drawing::FeatureViewPython'`, `'TechDraw::DrawViewDraft'`, `'TechDraw::DrawViewArch'`, - `'Drawing::FeatureViewPart'`, `'Drawing::FeatureViewAnnotation'` - - blocks : bool, optional - It defaults to `True`. Not used? + `'TechDraw::DrawViewPart'`, `'TechDraw::DrawViewAnnotation'` Returns ------- @@ -3994,19 +3979,8 @@ def getViewDXF(view, blocks=True): insert = "" blockcount = 1 - if view.isDerivedFrom("App::DocumentObjectGroup"): - for child in view.Group: - b, e = getViewDXF(child) - block += b - insert += e - - elif view.isDerivedFrom("Drawing::FeatureViewPython"): - if hasattr(view.Proxy, "getDXF"): - geom = view.Proxy.getDXF(view) - block, insert, blockcount = getViewBlock(geom, view, blockcount) - - elif view.isDerivedFrom("TechDraw::DrawViewDraft"): - geom = Draft.getDXF(view) + if view.isDerivedFrom("TechDraw::DrawViewDraft"): + geom = Draft.get_dxf(view) block, insert, blockcount = getViewBlock(geom, view, blockcount) elif view.isDerivedFrom("TechDraw::DrawViewArch"): @@ -4014,41 +3988,36 @@ def getViewDXF(view, blocks=True): geom = ArchSectionPlane.getDXF(view) block, insert, blockcount = getViewBlock(geom, view, blockcount) - elif view.isDerivedFrom("Drawing::FeatureViewPart"): - r = view.Rotation - if r != 0: - r = -r # fix rotation direction + elif view.isDerivedFrom("TechDraw::DrawViewPart"): import TechDraw - proj = TechDraw.projectToDXF(view.Source.Shape, view.Direction) - if dxfExportBlocks: - # change layer and set color and ltype to BYBLOCK (0) - proj = proj.replace("sheet_layer\n", - "0\n6\nBYBLOCK\n62\n0\n5\n_handle_\n") - block = "0\nBLOCK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockBegin\n2\n" - block += view.Name + str(blockcount) - block += "\n70\n0\n10\n0\n20\n0\n3\n" + view.Name + str(blockcount) - block += "\n1\n\n" - block += proj - block += "0\nENDBLK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockEnd\n" - insert += "0\nINSERT\n5\n_handle_\n8\n0\n6\nBYLAYER\n62\n256\n2\n" - insert += view.Name + str(blockcount) - insert += "\n10\n" + str(view.X) + "\n20\n" + str(-view.Y) - insert += "\n30\n0\n41\n" + str(view.Scale) - insert += "\n42\n" + str(view.Scale) + "\n43\n" + str(view.Scale) - insert += "\n50\n" + str(r) + "\n" - blockcount += 1 - else: - proj = proj.replace("sheet_layer\n", "0\n5\n_handle_\n") - insert += proj + for obj in view.Source: + proj = TechDraw.projectToDXF(obj.Shape, view.Direction) + if dxfExportBlocks: + # change layer and set color and ltype to BYBLOCK (0) + proj = proj.replace("sheet_layer\n", + "0\n6\nBYBLOCK\n62\n0\n5\n_handle_\n") + block += "0\nBLOCK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockBegin\n2\n" + block += view.Name + str(blockcount) + block += "\n70\n0\n10\n0\n20\n0\n3\n" + view.Name + str(blockcount) + block += "\n1\n\n" + block += proj + block += "0\nENDBLK\n5\n_handle_\n100\nAcDbEntity\n8\n0\n100\nAcDbBlockEnd\n" + insert += "0\nINSERT\n5\n_handle_\n8\n0\n6\nBYLAYER\n62\n256\n2\n" + insert += view.Name + str(blockcount) + insert += "\n10\n" + str(view.X) + "\n20\n" + str(view.Y) + insert += "\n30\n0\n41\n" + str(view.Scale) + insert += "\n42\n" + str(view.Scale) + "\n43\n" + str(view.Scale) + insert += "\n50\n" + str(view.Rotation) + "\n" + blockcount += 1 + else: + proj = proj.replace("sheet_layer\n", "0\n5\n_handle_\n") + insert += proj # view.Rotation is ignored - elif view.isDerivedFrom("Drawing::FeatureViewAnnotation"): - r = view.Rotation - if r != 0: - r = -r # fix rotation direction + elif view.isDerivedFrom("TechDraw::DrawViewAnnotation"): insert = "0\nTEXT\n5\n_handle_\n8\n0\n100\nAcDbEntity\n100\nAcDbText\n5\n_handle_" - insert += "\n10\n" + str(view.X) + "\n20\n" + str(-view.Y) + insert += "\n10\n" + str(view.X) + "\n20\n" + str(view.Y) insert += "\n30\n0\n40\n" + str(view.Scale/2) - insert += "\n50\n" + str(r) + insert += "\n50\n" + str(view.Rotation) insert += "\n1\n" + view.Text[0] + "\n" else: @@ -4056,37 +4025,6 @@ def getViewDXF(view, blocks=True): return block, insert -def exportPageLegacy(page, filename): - """Export a page created with Drawing or TechDraw workbenches. DEPRECATED. - - It uses the `importSVG` module to import the SVG information of `page` - into a temporary document, then the objects of this document - are used with the exporter to produce the DXF file, - and the temporary document is closed. - :: - temp = importSVG.open(page.PageResult) - export(temp.Objects, filename, nospline=True, lwPoly=false) - App.closeDocument(temp.Name) - - Parameters - ---------- - page : object derived from 'Drawing::FeaturePage' or 'TechDraw::DrawPage' - A Drawing or TechDraw page to export. - - filename : str - The path of the new DXF file. - - See also - -------- - exportPage, export, importSVG.open - """ - import importSVG - tempdoc = importSVG.open(page.PageResult) - tempobj = tempdoc.Objects - export(tempobj, filename, nospline=True, lwPoly=False) - FreeCAD.closeDocument(tempdoc.Name) - - def readPreferences(): """Read the preferences of the this module from the parameter database. diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index f08e2546d2..18581dbc6b 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -244,36 +244,46 @@ def getcolor(color): (r, g, b, a) RGBA float tuple, where each value is between 0.0 and 1.0. """ + if color == "none": + FreeCAD.Console.PrintMessage("Color defined as 'none', defaulting to black\n") + return (0.0, 0.0, 0.0, 0.0) if color[0] == "#": - # Color string '#12ab9f' - if len(color) == 7: + if len(color) == 7 or len(color) == 9: # Color string '#RRGGBB' or '#RRGGBBAA' r = float(int(color[1:3], 16) / 255.0) g = float(int(color[3:5], 16) / 255.0) - b = float(int(color[5:], 16) / 255.0) - # Color string '#1af' - elif len(color) == 4: + b = float(int(color[5:7], 16) / 255.0) + a = 1.0 + if len(color) == 9: + a = float(int(color[7:9], 16) / 255.0) + FreeCAD.Console.PrintMessage(f"Non standard color format #RRGGBBAA : {color}\n") + return (r, g, b, 1-a) + if len(color) == 4: # Color string '#RGB' # Expand the hex digits r = float(int(color[1], 16) * 17 / 255.0) g = float(int(color[2], 16) * 17 / 255.0) b = float(int(color[3], 16) * 17 / 255.0) - return (r, g, b, 0.0) - # Color string 'rgb(0.12,0.23,0.3,0.0)' - elif color.lower().startswith('rgb('): - cvalues = color[3:].lstrip('(').rstrip(')').replace('%', '').split(',') - if '%' in color: - r, g, b = [int(float(cv)) / 100.0 for cv in cvalues] - else: - r, g, b = [int(float(cv)) / 255.0 for cv in cvalues] - return (r, g, b, 0.0) - # Color string 'MediumAquamarine' - else: - v = svgcolorslower.get(color.lower()) - if v: - r, g, b = [float(vf) / 255.0 for vf in v] return (r, g, b, 0.0) - # for k, v in svgcolors.items(): - # if k.lower() == color.lower(): - # pass + if color.lower().startswith('rgb(') or color.lower().startswith('rgba('): # Color string 'rgb[a](0.12,0.23,0.3,0.0)' + cvalues = color.lstrip('rgba(').rstrip(')').replace('%', '').split(',') + if len(cvalues) == 3: + a = 1.0 + if '%' in color: + r, g, b = [int(float(cv)) / 100.0 for cv in cvalues] + else: + r, g, b = [int(float(cv)) / 255.0 for cv in cvalues] + if len(cvalues) == 4: + if '%' in color: + r, g, b, a = [int(float(cv)) / 100.0 for cv in cvalues] + else: + r, g, b, a = [int(float(cv)) / 255.0 for cv in cvalues] + return (r, g, b, 1-a) + # Trying named color like 'MediumAquamarine' + v = svgcolorslower.get(color.lower()) + if v: + r, g, b = [float(vf) / 255.0 for vf in v] + return (r, g, b, 0.0) + FreeCAD.Console.PrintWarning(f"Unknown color format : {color} : defaulting to black\n") + return (0.0, 0.0, 0.0, 0.0) def transformCopyShape(shape, m): diff --git a/src/Mod/TechDraw/App/DrawViewAnnotation.cpp b/src/Mod/TechDraw/App/DrawViewAnnotation.cpp index a921f1aaca..5d8f6ab94e 100644 --- a/src/Mod/TechDraw/App/DrawViewAnnotation.cpp +++ b/src/Mod/TechDraw/App/DrawViewAnnotation.cpp @@ -56,8 +56,8 @@ DrawViewAnnotation::DrawViewAnnotation() ADD_PROPERTY_TYPE(TextColor, (Preferences::normalColor()), vgroup, App::Prop_None, "Text color"); ADD_PROPERTY_TYPE(TextSize, (Preferences::labelFontSizeMM()), vgroup, App::Prop_None, "Text size"); - ADD_PROPERTY_TYPE(MaxWidth, (-1.0), vgroup, App::Prop_None, "Maximum width of the annotation block.\n -1 means no maximum width."); - ADD_PROPERTY_TYPE(LineSpace, (80), vgroup, App::Prop_None, "Line spacing in %. 100 means the height of a line."); + ADD_PROPERTY_TYPE(MaxWidth, (-1.0), vgroup, App::Prop_None, "Maximum width of the annotation block (in mm).\n -1 means no maximum width."); + ADD_PROPERTY_TYPE(LineSpace, (100), vgroup, App::Prop_None, "Line spacing in %. 100 means single spaced,\n 200 would be double spaced."); TextStyle.setEnums(TextStyleEnums); ADD_PROPERTY_TYPE(TextStyle, ((long)0), vgroup, App::Prop_None, "Text style"); @@ -85,22 +85,26 @@ void DrawViewAnnotation::onChanged(const App::Property* prop) void DrawViewAnnotation::handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property *prop) // transforms properties that had been changed { - // also check for changed properties of the base class - DrawView::handleChangedPropertyType(reader, TypeName, prop); + // also check for changed properties of the base class + DrawView::handleChangedPropertyType(reader, TypeName, prop); - // property LineSpace had the App::PropertyInteger and was changed to App::PropertyPercent - if (prop == &LineSpace && strcmp(TypeName, "App::PropertyInteger") == 0) { - App::PropertyInteger LineSpaceProperty; - // restore the PropertyInteger to be able to set its value - LineSpaceProperty.Restore(reader); - LineSpace.setValue(LineSpaceProperty.getValue()); - } - // property MaxWidth had the App::PropertyFloat and was changed to App::PropertyLength - else if (prop == &MaxWidth && strcmp(TypeName, "App::PropertyFloat") == 0) { - App::PropertyFloat MaxWidthProperty; - MaxWidthProperty.Restore(reader); - MaxWidth.setValue(MaxWidthProperty.getValue()); - } + // property LineSpace had the App::PropertyInteger and was changed to App::PropertyPercent + // the above change does not allow lines to be spaced wider than single space, so the change has been + // reverted, but we have to handle existing files that have a PropertyPercent + if (prop == &LineSpace && strcmp(TypeName, "App::PropertyPercent") == 0) { + App::PropertyPercent LineSpaceProperty; + // restore the PropertyPercent to be able to set its value + LineSpaceProperty.Restore(reader); + LineSpace.setValue(LineSpaceProperty.getValue()); + } + // property MaxWidth had the App::PropertyFloat and was changed to App::PropertyLength + // the above change did not consider that -1 is a magic value that indicates the line + // should not be broken. + else if (prop == &MaxWidth && strcmp(TypeName, "App::PropertyLength") == 0) { + App::PropertyFloat MaxWidthProperty; + MaxWidthProperty.Restore(reader); + MaxWidth.setValue(MaxWidthProperty.getValue()); + } } QRectF DrawViewAnnotation::getRect() const diff --git a/src/Mod/TechDraw/App/DrawViewAnnotation.h b/src/Mod/TechDraw/App/DrawViewAnnotation.h index 077dd9b27c..7f99903f78 100644 --- a/src/Mod/TechDraw/App/DrawViewAnnotation.h +++ b/src/Mod/TechDraw/App/DrawViewAnnotation.h @@ -48,9 +48,9 @@ public: App::PropertyFont Font; App::PropertyColor TextColor; App::PropertyLength TextSize; - App::PropertyPercent LineSpace; + App::PropertyInteger LineSpace; App::PropertyEnumeration TextStyle; // Plain, Bold, Italic, Bold-Italic - App::PropertyLength MaxWidth; + App::PropertyFloat MaxWidth; QRectF getRect() const override; diff --git a/src/Mod/TechDraw/App/XMLQuery.cpp b/src/Mod/TechDraw/App/XMLQuery.cpp index 69cc2b2e55..ea8c1b58f9 100644 --- a/src/Mod/TechDraw/App/XMLQuery.cpp +++ b/src/Mod/TechDraw/App/XMLQuery.cpp @@ -25,7 +25,7 @@ #ifndef _PreComp_ # include -#if QT_VERSION < QT_VERSION_CHECK(6,0,0) +#if 0 && QT_VERSION < QT_VERSION_CHECK(6,0,0) # include "QDomNodeModel.h" # include # include @@ -43,7 +43,7 @@ XMLQuery::XMLQuery(QDomDocument& dom) } -#if QT_VERSION < QT_VERSION_CHECK(6,0,0) +#if 0 && QT_VERSION < QT_VERSION_CHECK(6,0,0) bool XMLQuery::processItems(const QString& queryStr, const std::function& process) { QXmlQuery query(QXmlQuery::XQuery10); diff --git a/src/Mod/TechDraw/Gui/QGIViewAnnotation.cpp b/src/Mod/TechDraw/Gui/QGIViewAnnotation.cpp index 0872a488d0..3126051607 100644 --- a/src/Mod/TechDraw/Gui/QGIViewAnnotation.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewAnnotation.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -111,7 +112,21 @@ void QGIViewAnnotation::drawAnnotation() return; } - const std::vector& annoText = viewAnno->Text.getValues(); + const std::vector& annoRawText = viewAnno->Text.getValues(); + std::vector annoText; + // v0.19- stored text as escapedUnicode + // v0.20+ stores text as utf8 + for (auto& line : annoRawText) { + if (line.find("\\x") == std::string::npos) { + // not escaped + annoText.push_back(line); + } else { + // is escaped + std::string newLine = Base::Tools::escapedUnicodeToUtf8(line); + annoText.push_back(newLine); + } + } + int scaledSize = exactFontSize(viewAnno->Font.getValue(), viewAnno->TextSize.getValue()); //build HTML/CSS formatting around Text lines diff --git a/src/Mod/TechDraw/Gui/TaskCustomizeFormat.ui b/src/Mod/TechDraw/Gui/TaskCustomizeFormat.ui index 1a5e5d69e4..1dbac42ba3 100644 --- a/src/Mod/TechDraw/Gui/TaskCustomizeFormat.ui +++ b/src/Mod/TechDraw/Gui/TaskCustomizeFormat.ui @@ -6,10 +6,22 @@ 0 0 - 489 - 533 + 200 + 622 + + + 200 + 0 + + + + + 16777215 + 16777215 + + Format Symbols