diff --git a/src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx b/src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx index baa3898067..04baf70745 100644 --- a/src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx +++ b/src/BinLDrivers/BinLDrivers_DocumentStorageDriver.cxx @@ -106,6 +106,8 @@ void BinLDrivers_DocumentStorageDriver::Write (const Handle(CDM_Document)& theDo myDrivers = AttributeDrivers (myMsgDriver); Handle(TDF_Data) aData = aDoc->GetData(); FirstPass (aData->Root()); + if(aDoc->EmptyLabelsSavingMode()) + myEmptyLabels.Clear(); // // 1. Write info section (including types table) WriteInfoSection (aDoc, theOStream); diff --git a/src/DDocStd/DDocStd_ApplicationCommands.cxx b/src/DDocStd/DDocStd_ApplicationCommands.cxx index f54d2b6461..01653500a9 100644 --- a/src/DDocStd/DDocStd_ApplicationCommands.cxx +++ b/src/DDocStd/DDocStd_ApplicationCommands.cxx @@ -232,17 +232,17 @@ static Standard_Integer DDocStd_Save (Draw_Interpretor& di, //======================================================================= static Standard_Integer DDocStd_SaveAs (Draw_Interpretor& di, - Standard_Integer nb, - const char** a) -{ + Standard_Integer nb, + const char** a) +{ if (nb >= 3) { Handle(TDocStd_Document) D; if (!DDocStd::GetDocument(a[1],D)) return 1; TCollection_ExtendedString path (a[2]); Handle(TDocStd_Application) A = DDocStd::GetApplication(); PCDM_StoreStatus theStatus; - - Standard_Boolean anUseStream = Standard_False; + + Standard_Boolean anUseStream(Standard_False), isSaveEmptyLabels(Standard_False); for ( Standard_Integer i = 3; i < nb; i++ ) { if (!strcmp (a[i], "-stream")) @@ -250,9 +250,11 @@ static Standard_Integer DDocStd_SaveAs (Draw_Interpretor& di, di << "standard SEEKABLE stream is used\n"; anUseStream = Standard_True; break; + } else { + isSaveEmptyLabels = ((atoi (a[3])) != 0); + D->SetEmptyLabelsSavingMode(isSaveEmptyLabels); } } - if (anUseStream) { std::ofstream aFileStream; @@ -263,35 +265,35 @@ static Standard_Integer DDocStd_SaveAs (Draw_Interpretor& di, { theStatus = A->SaveAs(D,path); } - + if (theStatus != PCDM_SS_OK ) { switch ( theStatus ) { - case PCDM_SS_DriverFailure: { - di << "Error saving document: Could not store , no driver found to make it\n"; - break ; - } - case PCDM_SS_WriteFailure: { - di << "Error saving document: Write access failure\n"; - break; - } - case PCDM_SS_Failure: { - di << "Error saving document: Write failure\n" ; - break; - } - case PCDM_SS_Doc_IsNull: { - di << "Error saving document: No document to save\n"; - break ; - } - case PCDM_SS_No_Obj: { - di << "Error saving document: No objects written\n"; - break; - } - case PCDM_SS_Info_Section_Error: { - di << "Error saving document: Write info section failure\n" ; - break; - } - default: - break; + case PCDM_SS_DriverFailure: { + di << "Error saving document: Could not store , no driver found to make it\n"; + break ; + } + case PCDM_SS_WriteFailure: { + di << "Error saving document: Write access failure\n"; + break; + } + case PCDM_SS_Failure: { + di << "Error saving document: Write failure\n" ; + break; + } + case PCDM_SS_Doc_IsNull: { + di << "Error saving document: No document to save\n"; + break ; + } + case PCDM_SS_No_Obj: { + di << "Error saving document: No objects written\n"; + break; + } + case PCDM_SS_Info_Section_Error: { + di << "Error saving document: Write info section failure\n" ; + break; + } + default: + break; } return 1; } else { @@ -531,7 +533,7 @@ void DDocStd::ApplicationCommands(Draw_Interpretor& theCommands) __FILE__, DDocStd_Open, g); theCommands.Add("SaveAs", - "SaveAs DOC path [-stream]", + "SaveAs DOC path [saveEmptyLabels: 0|1] [-stream]", __FILE__, DDocStd_SaveAs, g); theCommands.Add("Save", diff --git a/src/TDocStd/TDocStd_Document.cxx b/src/TDocStd/TDocStd_Document.cxx index 1e0f7f3795..507bcc14b8 100644 --- a/src/TDocStd/TDocStd_Document.cxx +++ b/src/TDocStd/TDocStd_Document.cxx @@ -71,19 +71,20 @@ Handle(TDocStd_Document) TDocStd_Document::Get (const TDF_Label& acces) //======================================================================= -TDocStd_Document::TDocStd_Document(const TCollection_ExtendedString& aStorageFormat) : +TDocStd_Document::TDocStd_Document(const TCollection_ExtendedString& aStorageFormat) : myStorageFormat(aStorageFormat), myData (new TDF_Data()), myUndoLimit(0), mySaveTime(0), -myIsNestedTransactionMode(0) +myIsNestedTransactionMode(0), +mySaveEmptyLabels(Standard_False) { TDF_Transaction* pTr = new TDF_Transaction (myData,"UNDO"); myUndoTransaction = *pTr; delete pTr; TDocStd_Owner::SetDocument(myData,this); #ifdef SRN_DELTA_COMPACT - myFromUndo.Nullify(); + myFromUndo.Nullify(); myFromRedo.Nullify(); #endif } diff --git a/src/TDocStd/TDocStd_Document.hxx b/src/TDocStd/TDocStd_Document.hxx index 6c4fce304f..293273b4b5 100644 --- a/src/TDocStd/TDocStd_Document.hxx +++ b/src/TDocStd/TDocStd_Document.hxx @@ -218,24 +218,30 @@ public: //! to change format (advanced programming) //! ================ Standard_EXPORT virtual void Update (const Handle(CDM_Document)& aToDocument, const Standard_Integer aReferenceIdentifier, const Standard_Address aModifContext) Standard_OVERRIDE; - + Standard_EXPORT virtual TCollection_ExtendedString StorageFormat() const Standard_OVERRIDE; - + + //! Sets saving mode for empty labels. If Standard_True, empty labels will be saved. + Standard_EXPORT void SetEmptyLabelsSavingMode (const Standard_Boolean isAllowed); + + //! Returns saving mode for empty labels. + Standard_EXPORT Standard_Boolean EmptyLabelsSavingMode() const; + //! methods for the nested transaction mode Standard_EXPORT virtual void ChangeStorageFormat (const TCollection_ExtendedString& newStorageFormat); - + //! Sets nested transaction mode if isAllowed == Standard_True void SetNestedTransactionMode (const Standard_Boolean isAllowed = Standard_True); - + //! Returns Standard_True if mode is set - Standard_Boolean IsNestedTransactionMode() const; - + Standard_Boolean IsNestedTransactionMode() const; + //! if theTransactionOnly is True changes is denied outside transactions - void SetModificationMode (const Standard_Boolean theTransactionOnly); - + void SetModificationMode (const Standard_Boolean theTransactionOnly); + //! returns True if changes allowed only inside transactions - Standard_Boolean ModificationMode() const; - + Standard_Boolean ModificationMode() const; + //! Prepares document for closing Standard_EXPORT virtual void BeforeClose(); @@ -277,7 +283,7 @@ private: Standard_Boolean myIsNestedTransactionMode; TDF_DeltaList myUndoFILO; Standard_Boolean myOnlyTransactionModification; - + Standard_Boolean mySaveEmptyLabels; }; diff --git a/src/TDocStd/TDocStd_Document.lxx b/src/TDocStd/TDocStd_Document.lxx index 03b429eb75..33ba50119c 100644 --- a/src/TDocStd/TDocStd_Document.lxx +++ b/src/TDocStd/TDocStd_Document.lxx @@ -106,3 +106,22 @@ inline Standard_Integer TDocStd_Document::GetSavedTime () const { return mySaveTime; } + +//======================================================================= +//function : SetEmptyLabelsSavingMode +//purpose : Sets saving mode for empty labels. If Standard_True, +// empty labels will be saved. +//======================================================================= +inline void TDocStd_Document::SetEmptyLabelsSavingMode (const Standard_Boolean isAllowed) +{ + mySaveEmptyLabels = isAllowed; +} + +//======================================================================= +//function : EmptyLabelsSavingMode +//purpose : Returns saving mode for empty labels +//======================================================================= +inline Standard_Boolean TDocStd_Document::EmptyLabelsSavingMode() const +{ + return mySaveEmptyLabels; +} diff --git a/src/XmlMDF/XmlMDF.cxx b/src/XmlMDF/XmlMDF.cxx index 03eee48936..d688b6de10 100644 --- a/src/XmlMDF/XmlMDF.cxx +++ b/src/XmlMDF/XmlMDF.cxx @@ -34,6 +34,8 @@ #include #include #include +#include +#include IMPLEMENT_DOMSTRING (TagString, "tag") IMPLEMENT_DOMSTRING (LabelString, "label") @@ -131,7 +133,7 @@ Standard_Integer XmlMDF::WriteSubTree count += WriteSubTree(aChildLab, aLabElem, theRelocTable, theDrivers); } - if (count > 0) + if (count > 0 || TDocStd_Owner::GetDocument(theLabel.Data())->EmptyLabelsSavingMode()) { theElement.appendChild(aLabElem); diff --git a/tests/caf/basic/Y1 b/tests/caf/basic/Y1 new file mode 100644 index 0000000000..9c1ffaa4b6 --- /dev/null +++ b/tests/caf/basic/Y1 @@ -0,0 +1,78 @@ +#INTERFACE CAF +# Persistence functionality +# +# Testing feature: Saving empty labels (BinOcaf format) +# +# Testing command: SaveAs, Open +# + +puts "caf001-Y1" +set QA_DUP 0 + +set Lab1 [Label D 0:1:1] +set Lab2 [Label D 0:1:2] +set Lab3 [Label D 0:1:3] +## set List1 {0:1:1 0:1:2 0:1:3} +## set List2 {0:1:2} + +set aFile1 ${imagedir}/caf001-y1-1.cbf +set aFile2 ${imagedir}/caf001-y1-2.cbf + +#1. Open a new Document in BinOcaf format +# NewDocument D BinOcaf + +#2. Put integer attribute at the label Lab2 +SetInteger D $Lab2 321 +SetReal D $Lab2 871.33 + +#3. Save the Document with flag saveEmptyLabels = 1 +catch {SaveAs D ${aFile1} 1} +if { ![file exists ${aFile1}] } { + puts "There is not ${aFile} file; SaveAs command: Error writing binary file" + puts "Save ERROR" + return +} + +#4. Save the Document with flag saveEmptyLabels = 0 +catch {SaveAs D ${aFile2} 0} +if { ![file exists ${aFile2}] } { + puts "There is not ${aFile} file; SaveAs command: Error writing binary file" + puts "Save ERROR" + return +} + +#5. Open the just saved binary files +Close D +catch {Open ${aFile1} D1} +catch {Open ${aFile2} D2} + + +#5. Get list of child labels of main label (0:1) +set List1 [Children D1 0:1] +set List2 [Children D2 0:1] + +#6. Check length of the list of labels in aFile1 (to be len == 3) +set len1 [llength ${List1}] +if {$len1 != 3} { + puts "ERROR: Incorrect number of saved labels in cbf file, n = $len1" + return +} + +#7. Check length of the list of labels in aFile2 (to be len == 1) +set len2 [llength ${List2}] +if {$len2 != 1} { + puts "ERROR: Incorrect number of saved labels in cbf file, n = $len2" + return +} + +file delete ${aFile1} +file delete ${aFile2} +Close D1 +Close D2 + +puts "Saving empty labels: OK" + + + + + diff --git a/tests/caf/basic/Y2 b/tests/caf/basic/Y2 new file mode 100644 index 0000000000..77dc452952 --- /dev/null +++ b/tests/caf/basic/Y2 @@ -0,0 +1,78 @@ +#INTERFACE CAF +# Persistence functionality +# +# Testing feature: Saving empty labels (XmlOcaf format) +# +# Testing command: SaveAs, Open +# + +puts "caf001-Y2" +set QA_DUP 0 + +set Lab1 [Label D 0:1:1] +set Lab2 [Label D 0:1:2] +set Lab3 [Label D 0:1:3] +## set List1 {0:1:1 0:1:2 0:1:3} +## set List2 {0:1:2} + +set aFile1 ${imagedir}/caf001-y1-1.xml +set aFile2 ${imagedir}/caf001-y1-2.xml + +#1. Change Document format to XmlOcaf format +Format D XmlOcaf + +#2. Put integer attribute at the label Lab2 +SetInteger D $Lab2 321 +SetReal D $Lab2 871.33 + +#3. Save the Document with flag saveEmptyLabels = 1 +catch {SaveAs D ${aFile1} 1} +if { ![file exists ${aFile1}] } { + puts "There is not ${aFile} file; SaveAs command: Error writing xml file with empty labels" + puts "Save ERROR" + return +} + +#4. Save the Document with flag saveEmptyLabels = 0 +catch {SaveAs D ${aFile2} 0} +if { ![file exists ${aFile2}] } { + puts "There is not ${aFile} file; SaveAs command: Error writing xml file" + puts "Save ERROR" + return +} + +#5. Open the just saved xml files +Close D +catch {Open ${aFile1} D1} +catch {Open ${aFile2} D2} + + +#5. Get list of child labels of main label (0:1) +set List1 [Children D1 0:1] +set List2 [Children D2 0:1] + +#6. Check length of the list of labels in aFile1 (to be len == 3) +set len1 [llength ${List1}] +if {$len1 != 3} { + puts "ERROR: Incorrect number of saved labels in cbf file, n = $len1" + return +} + +#7. Check length of the list of labels in aFile2 (to be len == 1) +set len2 [llength ${List2}] +if {$len2 != 1} { + puts "ERROR: Incorrect number of saved labels in cbf file, n = $len2" + return +} + +file delete ${aFile1} +file delete ${aFile2} +Close D1 +Close D2 + +puts "Saving empty labels: OK" + + + + +