diff --git a/ChangeLog.txt b/ChangeLog.txt index 5588e386c..0d70c9784 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,7 @@ - [smart-pattern/valentina#122] Extend piece bounding rect. - Remember last selected export format. - [smart-pattern/valentina#123] Error inside Save layout dialog. +- Improve error handling for the dxf export. # Version 0.7.46 Mar 31, 2021 - Fix incorrect calculation of value for multisize measurements in Valentina. diff --git a/src/libs/vdxf/dxiface.cpp b/src/libs/vdxf/dxiface.cpp index 868713ab6..64b47e1c6 100644 --- a/src/libs/vdxf/dxiface.cpp +++ b/src/libs/vdxf/dxiface.cpp @@ -110,6 +110,11 @@ void dx_iface::writeEntity(DRW_Entity* e){ } } +std::string dx_iface::ErrorString() const +{ + return dxfW->ErrorString(); +} + void dx_iface::writeHeader(DRW_Header &data){ //complete copy of header vars: data = cData.headerC; diff --git a/src/libs/vdxf/dxiface.h b/src/libs/vdxf/dxiface.h index 78c9b11d2..212e5bd72 100644 --- a/src/libs/vdxf/dxiface.h +++ b/src/libs/vdxf/dxiface.h @@ -101,6 +101,8 @@ public: bool fileExport(bool binary); void writeEntity(DRW_Entity* e); + std::string ErrorString() const; + //reimplement virtual DRW_Interface functions //writer part, send all in class dx_data to writer virtual void writeHeader(DRW_Header& data) override; diff --git a/src/libs/vdxf/libdxfrw/libdxfrw.cpp b/src/libs/vdxf/libdxfrw/libdxfrw.cpp index 3f74513ba..4d065baf4 100644 --- a/src/libs/vdxf/libdxfrw/libdxfrw.cpp +++ b/src/libs/vdxf/libdxfrw/libdxfrw.cpp @@ -123,55 +123,66 @@ bool dxfRW::read(DRW_Interface *interface_, bool ext){ bool dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin){ bool isOk = false; std::ofstream filestr; + filestr.exceptions(std::ifstream::failbit | std::ifstream::badbit); version = ver; binFile = bin; iface = interface_; - if (binFile) { - filestr.open (fileName.c_str(), std::ios_base::out | std::ios::binary | std::ios::trunc); - //write sentinel - filestr << "AutoCAD Binary DXF\r\n" << static_cast(26) << '\0'; - writer = new dxfWriterBinary(&filestr); - DRW_DBG("dxfRW::read binary file\n"); - } else { - filestr.open (fileName.c_str(), std::ios_base::out | std::ios::trunc); - writer = new dxfWriterAscii(&filestr); - std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION); - writer->writeString(999, comm); - } - DRW_Header header; - iface->writeHeader(header); - writer->writeString(0, "SECTION"); - entCount =FIRSTHANDLE; - header.write(writer, version); - writer->writeString(0, "ENDSEC"); - if (ver > DRW::AC1009) { + try + { + if (binFile) { + filestr.open (fileName.c_str(), std::ios_base::out | std::ios::binary | std::ios::trunc); + //write sentinel + filestr << "AutoCAD Binary DXF\r\n" << static_cast(26) << '\0'; + writer = new dxfWriterBinary(&filestr); + DRW_DBG("dxfRW::read binary file\n"); + } else { + filestr.open (fileName.c_str(), std::ios_base::out | std::ios::trunc); + writer = new dxfWriterAscii(&filestr); + std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION); + writer->writeString(999, comm); + } + DRW_Header header; + iface->writeHeader(header); writer->writeString(0, "SECTION"); - writer->writeString(2, "CLASSES"); + entCount =FIRSTHANDLE; + header.write(writer, version); writer->writeString(0, "ENDSEC"); - } - writer->writeString(0, "SECTION"); - writer->writeString(2, "TABLES"); - writeTables(); - writer->writeString(0, "ENDSEC"); - writer->writeString(0, "SECTION"); - writer->writeString(2, "BLOCKS"); - writeBlocks(); - writer->writeString(0, "ENDSEC"); - - writer->writeString(0, "SECTION"); - writer->writeString(2, "ENTITIES"); - iface->writeEntities(); - writer->writeString(0, "ENDSEC"); - - if (version > DRW::AC1009) { + if (ver > DRW::AC1009) { + writer->writeString(0, "SECTION"); + writer->writeString(2, "CLASSES"); + writer->writeString(0, "ENDSEC"); + } writer->writeString(0, "SECTION"); - writer->writeString(2, "OBJECTS"); - writeObjects(); + writer->writeString(2, "TABLES"); + writeTables(); writer->writeString(0, "ENDSEC"); + writer->writeString(0, "SECTION"); + writer->writeString(2, "BLOCKS"); + writeBlocks(); + writer->writeString(0, "ENDSEC"); + + writer->writeString(0, "SECTION"); + writer->writeString(2, "ENTITIES"); + iface->writeEntities(); + writer->writeString(0, "ENDSEC"); + + if (version > DRW::AC1009) { + writer->writeString(0, "SECTION"); + writer->writeString(2, "OBJECTS"); + writeObjects(); + writer->writeString(0, "ENDSEC"); + } + writer->writeString(0, "EOF"); + filestr.flush(); + filestr.close(); + } + catch(std::ofstream::failure &writeErr) + { + errorString = writeErr.what(); + delete writer; + writer = nullptr; + return isOk; } - writer->writeString(0, "EOF"); - filestr.flush(); - filestr.close(); isOk = true; delete writer; writer = nullptr; @@ -1160,6 +1171,11 @@ bool dxfRW::writeDimension(DRW_Dimension *ent) { return true; } +std::string dxfRW::ErrorString() const +{ + return errorString; +} + bool dxfRW::writeInsert(DRW_Insert *ent){ writer->writeString(0, "INSERT"); writeEntity(ent); diff --git a/src/libs/vdxf/libdxfrw/libdxfrw.h b/src/libs/vdxf/libdxfrw/libdxfrw.h index fa20baced..c866b0a6a 100644 --- a/src/libs/vdxf/libdxfrw/libdxfrw.h +++ b/src/libs/vdxf/libdxfrw/libdxfrw.h @@ -72,6 +72,8 @@ public: bool writeDimension(DRW_Dimension *ent); void setEllipseParts(int parts){elParts = parts;} /*!< set parts munber when convert ellipse to polyline */ + std::string ErrorString() const; + private: Q_DISABLE_COPY(dxfRW) /// used by read() to parse the content of the file @@ -144,6 +146,7 @@ private: int currHandle; + std::string errorString{}; }; #endif // LIBDXFRW_H diff --git a/src/libs/vdxf/vdxfengine.cpp b/src/libs/vdxf/vdxfengine.cpp index 7badba13a..ad8887f86 100644 --- a/src/libs/vdxf/vdxfengine.cpp +++ b/src/libs/vdxf/vdxfengine.cpp @@ -138,8 +138,7 @@ bool VDxfEngine::begin(QPaintDevice *pdev) //--------------------------------------------------------------------------------------------------------------------- bool VDxfEngine::end() { - const bool res = input->fileExport(m_binary); - return res; + return input->fileExport(m_binary); } //--------------------------------------------------------------------------------------------------------------------- @@ -611,6 +610,12 @@ void VDxfEngine::SetYScale(const qreal &yscale) m_yscale = yscale; } +//--------------------------------------------------------------------------------------------------------------------- +QString VDxfEngine::ErrorString() const +{ + return QString::fromStdString(input->ErrorString()); +} + //--------------------------------------------------------------------------------------------------------------------- QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wswitch-default") @@ -668,7 +673,7 @@ bool VDxfEngine::ExportToAAMA(const QVector &details) for(auto detail : details) { - dx_ifaceBlock *detailBlock = new dx_ifaceBlock(); + auto *detailBlock = new dx_ifaceBlock(); QString blockName = detail.GetName(); if (m_version <= DRW::AC1009) @@ -691,7 +696,7 @@ bool VDxfEngine::ExportToAAMA(const QVector &details) input->AddBlock(detailBlock); - DRW_Insert *insert = new DRW_Insert(); + auto *insert = new DRW_Insert(); insert->name = blockName.toStdString(); insert->layer = '1'; @@ -869,7 +874,7 @@ bool VDxfEngine::ExportToASTM(const QVector &details) for(auto detail : details) { - dx_ifaceBlock *detailBlock = new dx_ifaceBlock(); + auto *detailBlock = new dx_ifaceBlock(); QString blockName = detail.GetName(); if (m_version <= DRW::AC1009) @@ -894,7 +899,7 @@ bool VDxfEngine::ExportToASTM(const QVector &details) input->AddBlock(detailBlock); - DRW_Insert *insert = new DRW_Insert(); + auto *insert = new DRW_Insert(); insert->name = blockName.toStdString(); insert->layer = '1'; diff --git a/src/libs/vdxf/vdxfengine.h b/src/libs/vdxf/vdxfengine.h index 9a95b63b7..623698e8c 100644 --- a/src/libs/vdxf/vdxfengine.h +++ b/src/libs/vdxf/vdxfengine.h @@ -98,6 +98,8 @@ public: qreal GetYScale() const; void SetYScale(const qreal &yscale); + QString ErrorString() const; + private: Q_DISABLE_COPY(VDxfEngine) QSize size; diff --git a/src/libs/vdxf/vdxfpaintdevice.cpp b/src/libs/vdxf/vdxfpaintdevice.cpp index 23622d211..495d75f83 100644 --- a/src/libs/vdxf/vdxfpaintdevice.cpp +++ b/src/libs/vdxf/vdxfpaintdevice.cpp @@ -214,6 +214,12 @@ bool VDxfPaintDevice::ExportToASTM(const QVector &details) const return res; } +//--------------------------------------------------------------------------------------------------------------------- +QString VDxfPaintDevice::ErrorString() const +{ + return engine->ErrorString(); +} + //--------------------------------------------------------------------------------------------------------------------- int VDxfPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const { diff --git a/src/libs/vdxf/vdxfpaintdevice.h b/src/libs/vdxf/vdxfpaintdevice.h index a78f762f8..a03e6df9f 100644 --- a/src/libs/vdxf/vdxfpaintdevice.h +++ b/src/libs/vdxf/vdxfpaintdevice.h @@ -75,6 +75,8 @@ public: bool ExportToAAMA(const QVector &details) const; bool ExportToASTM(const QVector &details) const; + QString ErrorString() const; + protected: virtual int metric(PaintDeviceMetric metric) const override; private: diff --git a/src/libs/vlayout/vlayoutexporter.cpp b/src/libs/vlayout/vlayoutexporter.cpp index 9ffceca45..42c168cd5 100644 --- a/src/libs/vlayout/vlayoutexporter.cpp +++ b/src/libs/vlayout/vlayoutexporter.cpp @@ -301,7 +301,11 @@ void VLayoutExporter::ExportToFlatDXF(QGraphicsScene *scene, const QListrender(&painter, m_imageRect, m_imageRect, Qt::IgnoreAspectRatio); - painter.end(); + if (not painter.end()) + { + qCritical() << tr("Can't create an flat dxf file.") + << generator.ErrorString(); + } } RestoreTextAfterDXF(endStringPlaceholder, details); @@ -319,7 +323,11 @@ void VLayoutExporter::ExportToAAMADXF(const QVector &details) cons generator.setInsunits(VarInsunits::Millimeters);// Decided to always use mm. See issue #745 generator.SetXScale(m_xScale); generator.SetYScale(m_yScale); - generator.ExportToAAMA(details); + if (not generator.ExportToAAMA(details)) + { + qCritical() << tr("Can't create an AAMA dxf file.") + << generator.ErrorString(); + } } //--------------------------------------------------------------------------------------------------------------------- @@ -334,7 +342,11 @@ void VLayoutExporter::ExportToASTMDXF(const QVector &details) cons generator.setInsunits(VarInsunits::Millimeters);// Decided to always use mm. See issue #745 generator.SetXScale(m_xScale); generator.SetYScale(m_yScale); - generator.ExportToASTM(details); + if (not generator.ExportToASTM(details)) + { + qCritical() << tr("Can't create an ASTM dxf file.") + << generator.ErrorString(); + } } //---------------------------------------------------------------------------------------------------------------------