diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-07-17 20:20:16 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-07-18 14:55:35 -0400 |
commit | ca20a53315eaea218c693e0de2026eb6f957331f (patch) | |
tree | 8c9386bfa1e99d9520f4778cc98605d896942102 /sc | |
parent | 6c24bf4cab7e2a9514cf99160a31728835198741 (diff) |
bnc#885548: Adjust xlsx export of revisions to get it to work in Excel.
(cherry picked from commit fa44673e154ed4fb0b518b8850e2f6e4b9069531)
Conflicts:
sc/source/filter/inc/XclExpChangeTrack.hxx
sc/source/filter/xcl97/XclExpChangeTrack.cxx
sc/inc/cellvalue.hxx
sc/source/core/data/cellvalue.cxx
Change-Id: I0058d9ddfea545390e615a3030171a366e333c85
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/cellvalue.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/cellvalue.cxx | 7 | ||||
-rw-r--r-- | sc/source/filter/excel/xestream.cxx | 7 | ||||
-rw-r--r-- | sc/source/filter/inc/XclExpChangeTrack.hxx | 84 | ||||
-rw-r--r-- | sc/source/filter/inc/xestream.hxx | 10 | ||||
-rw-r--r-- | sc/source/filter/xcl97/XclExpChangeTrack.cxx | 346 |
6 files changed, 299 insertions, 156 deletions
diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx index c2606b511e72..8e2e64a42b07 100644 --- a/sc/inc/cellvalue.hxx +++ b/sc/inc/cellvalue.hxx @@ -53,6 +53,7 @@ struct SC_DLLPUBLIC ScCellValue void set( double fValue ); void set( const svl::SharedString& rStr ); void set( const EditTextObject& rEditText ); + void set( EditTextObject* pEditText ); void set( const ScFormulaCell& rFormula ); void set( ScFormulaCell* pFormula ); diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx index 12ef30272e62..92298cfe336a 100644 --- a/sc/source/core/data/cellvalue.cxx +++ b/sc/source/core/data/cellvalue.cxx @@ -248,6 +248,13 @@ void ScCellValue::set( const EditTextObject& rEditText ) mpEditText = rEditText.Clone(); } +void ScCellValue::set( EditTextObject* pEditText ) +{ + clear(); + meType = CELLTYPE_EDIT; + mpEditText = pEditText; +} + void ScCellValue::set( const ScFormulaCell& rFormula ) { clear(); diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx index df08d2c811a3..47dba9e656a6 100644 --- a/sc/source/filter/excel/xestream.cxx +++ b/sc/source/filter/excel/xestream.cxx @@ -842,6 +842,13 @@ const char* XclXmlUtils::ToPsz( bool b ) return b ? "true" : "false"; } +const char* XclXmlUtils::ToPsz10( bool b ) +{ + // xlsx seems to use "1" or "0" for boolean values. I wonder it ever uses + // the "true" "false" variant. + return b ? "1" : "0"; +} + sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue ) { pStream->startElement( nElement, FSEND ); diff --git a/sc/source/filter/inc/XclExpChangeTrack.hxx b/sc/source/filter/inc/XclExpChangeTrack.hxx index 3818535b7d4f..c7ee38909794 100644 --- a/sc/source/filter/inc/XclExpChangeTrack.hxx +++ b/sc/source/filter/inc/XclExpChangeTrack.hxx @@ -29,7 +29,16 @@ #include "ftools.hxx" #include "excrecds.hxx" -//___________________________________________________________________ +#include <boost/ptr_container/ptr_vector.hpp> + +class ExcXmlRecord : public ExcRecord +{ +public: + virtual sal_Size GetLen() const SAL_OVERRIDE; + virtual sal_uInt16 GetNum() const SAL_OVERRIDE; + virtual void Save( XclExpStream& rStrm ) SAL_OVERRIDE; +}; + // XclExpUserBView - one UserBView record for each user class XclExpUserBView : public ExcRecord @@ -238,42 +247,61 @@ public: virtual void SaveXml( XclExpXmlStream& rStrm ); }; -//___________________________________________________________________ +class XclExpXmlChTrHeaders : public ExcXmlRecord +{ + sal_uInt8 maGUID[16]; +public: + void SetGUID( const sal_uInt8* pGUID ); + + virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE; +}; + +class XclExpChTrTabIdBuffer; +class XclExpChTrAction; + +class XclExpXmlChTrHeader : public ExcXmlRecord +{ + OUString maUserName; + DateTime maDateTime; + sal_uInt8 maGUID[16]; + sal_Int32 mnLogNumber; + sal_uInt32 mnMinAction; + sal_uInt32 mnMaxAction; + + std::vector<sal_uInt16> maTabBuffer; + std::vector<XclExpChTrAction*> maActions; + +public: + XclExpXmlChTrHeader( + const OUString& rUserName, const DateTime& rDateTime, const sal_uInt8* pGUID, + sal_Int32 nLogNumber, const XclExpChTrTabIdBuffer& rBuf ); + + virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE; + + void AppendAction( XclExpChTrAction* pAction ); +}; + // XclExpChTrInfo - header of action group of a user class XclExpChTrInfo : public ExcRecord { private: XclExpString sUsername; - sal_Int32 mnLogNumber; DateTime aDateTime; sal_uInt8 aGUID[ 16 ]; virtual void SaveCont( XclExpStream& rStrm ); public: - inline XclExpChTrInfo( - const OUString& rUsername, - const DateTime& rDateTime, - const sal_uInt8* pGUID, - sal_Int32 nLogNumber ); + XclExpChTrInfo( const OUString& rUsername, const DateTime& rDateTime, + const sal_uInt8* pGUID ); + virtual ~XclExpChTrInfo(); virtual sal_uInt16 GetNum() const; virtual sal_Size GetLen() const; - - virtual void SaveXml( XclExpXmlStream& rStrm ); }; -inline XclExpChTrInfo::XclExpChTrInfo( const OUString& rUsername, const DateTime& rDateTime, const sal_uInt8* pGUID, sal_Int32 nLogNumber ) : - sUsername( rUsername ), - mnLogNumber( nLogNumber ), - aDateTime( rDateTime ) -{ - memcpy( aGUID, pGUID, 16 ); -} - -//___________________________________________________________________ // XclExpChTrTabIdBuffer - buffer for tab id's class XclExpChTrTabIdBuffer @@ -309,7 +337,6 @@ class XclExpChTrTabId : public ExcRecord private: sal_uInt16* pBuffer; sal_uInt16 nTabCount; - bool mbInRevisionHeaders; inline void Clear() { if( pBuffer ) delete[] pBuffer; pBuffer = NULL; } @@ -317,16 +344,14 @@ private: public: inline XclExpChTrTabId( sal_uInt16 nCount ) : - pBuffer( NULL ), nTabCount( nCount ), mbInRevisionHeaders( false ) {} - XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer, bool bInRevisionHeaders = false ); + pBuffer( NULL ), nTabCount( nCount ) {} + XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer ); virtual ~XclExpChTrTabId(); void Copy( const XclExpChTrTabIdBuffer& rBuffer ); virtual sal_uInt16 GetNum() const; virtual sal_Size GetLen() const; - - virtual void SaveXml( XclExpXmlStream& rStrm ); }; //___________________________________________________________________ @@ -375,8 +400,7 @@ protected: // do something after writing the record virtual void CompleteSaveAction( XclExpStream& rStrm ) const; - inline sal_uInt32 GetActionNumber() const { return nIndex; } - inline sal_Bool GetAccepted() const { return bAccepted; } + inline bool GetAccepted() const { return bAccepted; } public: XclExpChTrAction( @@ -399,6 +423,7 @@ public: virtual sal_Size GetLen() const; inline XclExpChTrAction* GetAddAction() { return pAddAction; } + inline sal_uInt32 GetActionNumber() const { return nIndex; } }; inline void XclExpChTrAction::Write2DAddress( XclExpStream& rStrm, const ScAddress& rAddress ) const @@ -590,11 +615,12 @@ public: class XclExpChangeTrack : protected XclExpRoot { -private: - std::vector<ExcRecord*> aRecList; // list of "Revision Log" stream records + typedef boost::ptr_vector<ExcRecord> RecListType; + typedef boost::ptr_vector<XclExpChTrTabIdBuffer> TabIdBufferType; + RecListType maRecList; // list of "Revision Log" stream records std::stack<XclExpChTrAction*> aActionStack; XclExpChTrTabIdBuffer* pTabIdBuffer; - std::vector<XclExpChTrTabIdBuffer*> maBuffers; + TabIdBufferType maBuffers; ScDocument* pTempDoc; // empty document diff --git a/sc/source/filter/inc/xestream.hxx b/sc/source/filter/inc/xestream.hxx index e29ed1ad65bf..f33f0c0b01d5 100644 --- a/sc/source/filter/inc/xestream.hxx +++ b/sc/source/filter/inc/xestream.hxx @@ -286,8 +286,18 @@ public: static OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 ); static OUString ToOUString( ScDocument& rDocument, const ScAddress& rAddress, const ScTokenArray* pTokenArray ); static OUString ToOUString( const XclExpString& s ); + + /** + * @return const char* literal "true" for true value, or literal "false" + * for false value. + */ static const char* ToPsz( bool b ); + /** + * @return literal "1" for true value, or literal "0" for false value. + */ + static const char* ToPsz10( bool b ); + static sax_fastparser::FSHelperPtr WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue ); static sax_fastparser::FSHelperPtr WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int64 nValue ); static sax_fastparser::FSHelperPtr WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const char* sValue ); diff --git a/sc/source/filter/xcl97/XclExpChangeTrack.cxx b/sc/source/filter/xcl97/XclExpChangeTrack.cxx index 3a3655d32c05..fe27e925a31c 100644 --- a/sc/source/filter/xcl97/XclExpChangeTrack.cxx +++ b/sc/source/filter/xcl97/XclExpChangeTrack.cxx @@ -40,7 +40,7 @@ static OString lcl_GuidToOString( sal_uInt8 aGuid[ 16 ] ) { char sBuf[ 40 ]; snprintf( sBuf, sizeof( sBuf ), - "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", aGuid[ 0 ], aGuid[ 1 ], aGuid[ 2 ], aGuid[ 3 ], aGuid[ 4 ], aGuid[ 5 ], aGuid[ 6 ], aGuid[ 7 ], aGuid[ 8 ], aGuid[ 9 ], aGuid[ 10 ], aGuid[ 11 ], aGuid[ 12 ], aGuid[ 13 ], aGuid[ 14 ], aGuid[ 15 ] ); return OString( sBuf ); @@ -394,7 +394,149 @@ void XclExpChTrHeader::SaveXml( XclExpXmlStream& rRevisionHeadersStrm ) pHeaders->write( ">" ); } -//___________________________________________________________________ +void XclExpXmlChTrHeaders::SetGUID( const sal_uInt8* pGUID ) +{ + memcpy(maGUID, pGUID, 16); +} + +void XclExpXmlChTrHeaders::SaveXml( XclExpXmlStream& rStrm ) +{ + sax_fastparser::FSHelperPtr pHeaders = rStrm.GetCurrentStream(); + + pHeaders->write("<")->writeId(XML_headers); + + rStrm.WriteAttributes( + XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main", + FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships", + XML_guid, lcl_GuidToOString(maGUID).getStr(), + XML_lastGuid, NULL, // OOXTODO + XML_shared, NULL, // OOXTODO + XML_diskRevisions, NULL, // OOXTODO + XML_history, NULL, // OOXTODO + XML_trackRevisions, NULL, // OOXTODO + XML_exclusive, NULL, // OOXTODO + XML_revisionId, NULL, // OOXTODO + XML_version, NULL, // OOXTODO + XML_keepChangeHistory, NULL, // OOXTODO + XML_protected, NULL, // OOXTODO + XML_preserveHistory, NULL, // OOXTODO + FSEND); + + pHeaders->write(">"); +} + +XclExpXmlChTrHeader::XclExpXmlChTrHeader( + const OUString& rUserName, const DateTime& rDateTime, const sal_uInt8* pGUID, + sal_Int32 nLogNumber, const XclExpChTrTabIdBuffer& rBuf ) : + maUserName(rUserName), maDateTime(rDateTime), mnLogNumber(nLogNumber), + mnMinAction(0), mnMaxAction(0) +{ + memcpy(maGUID, pGUID, 16); + if (rBuf.GetBufferCount()) + { + maTabBuffer.resize(rBuf.GetBufferCount()); + rBuf.GetBufferCopy(&maTabBuffer[0]); + } +} + +void XclExpXmlChTrHeader::SaveXml( XclExpXmlStream& rStrm ) +{ + sax_fastparser::FSHelperPtr pHeader = rStrm.GetCurrentStream(); + + pHeader->write("<")->writeId(XML_header); + + OUString aRelId; + sax_fastparser::FSHelperPtr pRevLogStrm = rStrm.CreateOutputStream( + XclXmlUtils::GetStreamName("xl/revisions/", "revisionLog", mnLogNumber), + XclXmlUtils::GetStreamName(NULL, "revisionLog", mnLogNumber), + rStrm.GetCurrentStream()->getOutputStream(), + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml", + CREATE_OFFICEDOC_RELATION_TYPE("revisionLog"), + &aRelId); + + rStrm.WriteAttributes( + XML_guid, lcl_GuidToOString(maGUID).getStr(), + XML_dateTime, lcl_DateTimeToOString(maDateTime).getStr(), + XML_userName, XclXmlUtils::ToOString(maUserName).getStr(), + FSNS(XML_r, XML_id), XclXmlUtils::ToOString(aRelId).getStr(), + FSEND); + + if (mnMinAction) + rStrm.WriteAttributes(XML_minRId, OString::number(mnMinAction).getStr(), FSEND); + + if (mnMaxAction) + rStrm.WriteAttributes(XML_maxRId, OString::number(mnMaxAction).getStr(), FSEND); + + if (!maTabBuffer.empty()) + // next available sheet index. + rStrm.WriteAttributes(XML_maxSheetId, OString::number(maTabBuffer.back()+1).getStr(), FSEND); + + pHeader->write(">"); + + if (!maTabBuffer.empty()) + { + // Write sheet index map. + size_t n = maTabBuffer.size(); + pHeader->startElement( + XML_sheetIdMap, + XML_count, OString::number(n).getStr(), + FSEND); + + for (size_t i = 0; i < n; ++i) + { + pHeader->singleElement( + XML_sheetId, + XML_val, OString::number(maTabBuffer[i]).getStr(), + FSEND); + } + pHeader->endElement(XML_sheetIdMap); + } + + // Write all revision logs in a separate stream. + + rStrm.PushStream(pRevLogStrm); + + pRevLogStrm->write("<")->writeId(XML_revisions); + + rStrm.WriteAttributes( + XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main", + FSNS(XML_xmlns, XML_r), "http://schemas.openxmlformats.org/officeDocument/2006/relationships", + FSEND); + + pRevLogStrm->write(">"); + + std::vector<XclExpChTrAction*>::iterator it = maActions.begin(), itEnd = maActions.end(); + for (; it != itEnd; ++it) + { + XclExpChTrAction* p = *it; + p->SaveXml(rStrm); + } + + pRevLogStrm->write("</")->writeId(XML_revisions)->write(">"); + + rStrm.PopStream(); + + pHeader->write("</")->writeId(XML_header)->write(">"); +} + +void XclExpXmlChTrHeader::AppendAction( XclExpChTrAction* pAction ) +{ + sal_uInt32 nActionNum = pAction->GetActionNumber(); + if (!mnMinAction || mnMinAction > nActionNum) + mnMinAction = nActionNum; + + if (!mnMaxAction || mnMaxAction < nActionNum) + mnMaxAction = nActionNum; + + maActions.push_back(pAction); +} + +XclExpChTrInfo::XclExpChTrInfo( const OUString& rUsername, const DateTime& rDateTime, const sal_uInt8* pGUID ) : + sUsername( rUsername ), + aDateTime( rDateTime ) +{ + memcpy( aGUID, pGUID, 16 ); +} XclExpChTrInfo::~XclExpChTrInfo() { @@ -424,35 +566,6 @@ sal_Size XclExpChTrInfo::GetLen() const return 158; } -void XclExpChTrInfo::SaveXml( XclExpXmlStream& rRevisionHeadersStrm ) -{ - sax_fastparser::FSHelperPtr pHeader = rRevisionHeadersStrm.GetCurrentStream(); - - OUString sRelationshipId; - sax_fastparser::FSHelperPtr pRevisionLog = rRevisionHeadersStrm.CreateOutputStream( - XclXmlUtils::GetStreamName( "xl/revisions/", "revisionLog", mnLogNumber ), - XclXmlUtils::GetStreamName( NULL, "revisionLog", mnLogNumber ), - rRevisionHeadersStrm.GetCurrentStream()->getOutputStream(), - "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionLog", - &sRelationshipId ); - - rRevisionHeadersStrm.WriteAttributes( - XML_guid, lcl_GuidToOString( aGUID ).getStr(), - XML_dateTime, lcl_DateTimeToOString( aDateTime ).getStr(), - XML_maxSheetId, NULL, // OOXTODO - XML_userName, XclXmlUtils::ToOString( sUsername ).getStr(), - FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sRelationshipId ).getStr(), - XML_minRId, NULL, // OOXTODO - XML_maxRId, NULL, // OOXTODO - FSEND ); - pHeader->write( ">" ); - - rRevisionHeadersStrm.PushStream( pRevisionLog ); -} - -//___________________________________________________________________ - XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount ) : nBufSize( nCount ), nLastId( nCount ) @@ -523,11 +636,8 @@ void XclExpChTrTabIdBuffer::Remove() nLastId--; } -//___________________________________________________________________ - -XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer, bool bInRevisionHeaders ) +XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer ) : nTabCount( rBuffer.GetBufferCount() ) - , mbInRevisionHeaders( bInRevisionHeaders ) { pBuffer = new sal_uInt16[ nTabCount ]; rBuffer.GetBufferCopy( pBuffer ); @@ -567,31 +677,6 @@ sal_Size XclExpChTrTabId::GetLen() const return nTabCount << 1; } -void XclExpChTrTabId::SaveXml( XclExpXmlStream& rRevisionLogStrm ) -{ - if( !mbInRevisionHeaders ) - return; - - sax_fastparser::FSHelperPtr pRevisionLog = rRevisionLogStrm.GetCurrentStream(); - rRevisionLogStrm.PopStream(); - - sax_fastparser::FSHelperPtr pHeader = rRevisionLogStrm.GetCurrentStream(); - pHeader->startElement( XML_sheetIdMap, - XML_count, OString::number( nTabCount ).getStr(), - FSEND ); - for( int i = 0; i < nTabCount; ++i ) - { - pHeader->singleElement( XML_sheetId, - XML_val, OString::number( pBuffer[ i ] ).getStr(), - FSEND ); - } - pHeader->endElement( XML_sheetIdMap ); - - rRevisionLogStrm.PushStream( pRevisionLog ); -} - -//___________________________________________________________________ - // ! does not copy additional actions XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction& rCopy ) : ExcRecord( rCopy ), @@ -1137,11 +1222,12 @@ void XclExpChTrInsert::SaveXml( XclExpXmlStream& rRevisionLogStrm ) XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure. XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted? XML_sId, OString::number( GetTabId( aRange.aStart.Tab() ) ).getStr(), - XML_eol, NULL, // OOXTODO: not supported? + XML_eol, XclXmlUtils::ToPsz10(mbEndOfList), XML_ref, XclXmlUtils::ToOString( aRange ).getStr(), XML_action, lcl_GetAction( nOpCode ), XML_edge, NULL, // OOXTODO: ??? FSEND ); + // OOXTODO: does this handle XML_rfmt, XML_undo? XclExpChTrAction* pAction = GetAddAction(); while( pAction != NULL ) @@ -1329,17 +1415,6 @@ void XclExpChTr0x014A::SaveXml( XclExpXmlStream& rStrm ) pStream->endElement( XML_rfmt ); } -//___________________________________________________________________ - -class ExcXmlRecord : public ExcRecord -{ -public: - virtual sal_Size GetLen() const; - virtual sal_uInt16 GetNum() const; - virtual void Save( XclExpStream& rStrm ); - virtual void SaveXml( XclExpXmlStream& rStrm ) = 0; -}; - sal_Size ExcXmlRecord::GetLen() const { return 0; @@ -1458,66 +1533,83 @@ XclExpChangeTrack::XclExpChangeTrack( const XclExpRoot& rRoot ) : } // build record list - pHeader = new XclExpChTrHeader; - aRecList.push_back( new StartXmlElement( XML_headers, StartXmlElement::WRITE_NAMESPACES ) ); - aRecList.push_back( pHeader ); - aRecList.push_back( new XclExpChTr0x0195 ); - aRecList.push_back( new XclExpChTr0x0194( *pTempChangeTrack ) ); - - OUString sLastUsername; - DateTime aLastDateTime( DateTime::EMPTY ); - sal_uInt32 nIndex = 1; - sal_Int32 nLogNumber = 1; - while( !aActionStack.empty() ) + if (GetOutput() == EXC_OUTPUT_BINARY) { - XclExpChTrAction* pAction = aActionStack.top(); - aActionStack.pop(); - - if( (nIndex == 1) || pAction->ForceInfoRecord() || - (pAction->GetUsername() != sLastUsername) || - (pAction->GetDateTime() != aLastDateTime) ) + pHeader = new XclExpChTrHeader; + maRecList.push_back( pHeader ); + maRecList.push_back( new XclExpChTr0x0195 ); + maRecList.push_back( new XclExpChTr0x0194( *pTempChangeTrack ) ); + + OUString sLastUsername; + DateTime aLastDateTime( DateTime::EMPTY ); + sal_uInt32 nIndex = 1; + sal_Int32 nLogNumber = 1; + while( !aActionStack.empty() ) { - if( nIndex != 1 ) + XclExpChTrAction* pAction = aActionStack.top(); + aActionStack.pop(); + + if( (nIndex == 1) || pAction->ForceInfoRecord() || + (pAction->GetUsername() != sLastUsername) || + (pAction->GetDateTime() != aLastDateTime) ) { - aRecList.push_back( new EndXmlElement( XML_revisions ) ); - aRecList.push_back( new EndHeaderElement() ); + lcl_GenerateGUID( aGUID, bValidGUID ); + sLastUsername = pAction->GetUsername(); + aLastDateTime = pAction->GetDateTime(); + + nLogNumber++; + maRecList.push_back( new XclExpChTrInfo(sLastUsername, aLastDateTime, aGUID) ); + maRecList.push_back( new XclExpChTrTabId(pAction->GetTabIdBuffer()) ); + pHeader->SetGUID( aGUID ); } + pAction->SetIndex( nIndex ); + maRecList.push_back( pAction ); + } - lcl_GenerateGUID( aGUID, bValidGUID ); - sLastUsername = pAction->GetUsername(); - aLastDateTime = pAction->GetDateTime(); + pHeader->SetGUID( aGUID ); + pHeader->SetCount( nIndex - 1 ); + maRecList.push_back( new ExcEof ); + } + else + { + XclExpXmlChTrHeaders* pHeaders = new XclExpXmlChTrHeaders; + maRecList.push_back(pHeaders); + + OUString sLastUsername; + DateTime aLastDateTime(DateTime::EMPTY); + sal_uInt32 nIndex = 1; + sal_Int32 nLogNumber = 1; + XclExpXmlChTrHeader* pCurHeader = NULL; + + while (!aActionStack.empty()) + { + XclExpChTrAction* pAction = aActionStack.top(); + aActionStack.pop(); - aRecList.push_back( new StartXmlElement( XML_header, 0 ) ); - aRecList.push_back( new XclExpChTrInfo( sLastUsername, aLastDateTime, aGUID, nLogNumber++ ) ); - aRecList.push_back( new XclExpChTrTabId( pAction->GetTabIdBuffer(), true ) ); - aRecList.push_back( new StartXmlElement( XML_revisions, StartXmlElement::WRITE_NAMESPACES | StartXmlElement::CLOSE_ELEMENT ) ); - pHeader->SetGUID( aGUID ); + if( (nIndex == 1) || pAction->ForceInfoRecord() || + (pAction->GetUsername() != sLastUsername) || + (pAction->GetDateTime() != aLastDateTime) ) + { + lcl_GenerateGUID( aGUID, bValidGUID ); + sLastUsername = pAction->GetUsername(); + aLastDateTime = pAction->GetDateTime(); + + pCurHeader = new XclExpXmlChTrHeader(sLastUsername, aLastDateTime, aGUID, nLogNumber, pAction->GetTabIdBuffer()); + maRecList.push_back(pCurHeader); + nLogNumber++; + pHeaders->SetGUID(aGUID); + } + pAction->SetIndex(nIndex); + pCurHeader->AppendAction(pAction); } - pAction->SetIndex( nIndex ); - aRecList.push_back( pAction ); - } - pHeader->SetGUID( aGUID ); - pHeader->SetCount( nIndex - 1 ); - if( nLogNumber > 1 ) - { - aRecList.push_back( new EndXmlElement( XML_revisions ) ); - aRecList.push_back( new EndHeaderElement() ); + pHeaders->SetGUID(aGUID); + maRecList.push_back(new EndXmlElement(XML_headers)); } - aRecList.push_back( new EndXmlElement( XML_headers ) ); - aRecList.push_back( new ExcEof ); } XclExpChangeTrack::~XclExpChangeTrack() { - std::vector<ExcRecord*>::iterator prIter; - for ( prIter = aRecList.begin(); prIter != aRecList.end(); ++prIter ) - delete *prIter; - - std::vector<XclExpChTrTabIdBuffer*>::iterator pIter; - for ( pIter = maBuffers.begin(); pIter != maBuffers.end(); ++pIter ) - delete *pIter; - while( !aActionStack.empty() ) { delete aActionStack.top(); @@ -1613,7 +1705,7 @@ sal_Bool XclExpChangeTrack::WriteUserNamesStream() void XclExpChangeTrack::Write() { - if( aRecList.empty() ) + if (maRecList.empty()) return; if( WriteUserNamesStream() ) @@ -1624,9 +1716,9 @@ void XclExpChangeTrack::Write() { XclExpStream aXclStrm( *xSvStrm, GetRoot(), EXC_MAXRECSIZE_BIFF8 + 8 ); - std::vector<ExcRecord*>::iterator pIter; - for ( pIter = aRecList.begin(); pIter != aRecList.end(); ++pIter ) - (*pIter)->Save(aXclStrm); + RecListType::iterator pIter; + for (pIter = maRecList.begin(); pIter != maRecList.end(); ++pIter) + pIter->Save(aXclStrm); xSvStrm->Commit(); } @@ -1654,7 +1746,7 @@ static void lcl_WriteUserNamesXml( XclExpXmlStream& rWorkbookStrm ) void XclExpChangeTrack::WriteXml( XclExpXmlStream& rWorkbookStrm ) { - if( aRecList.empty() ) + if (maRecList.empty()) return; lcl_WriteUserNamesXml( rWorkbookStrm ); @@ -1670,9 +1762,9 @@ void XclExpChangeTrack::WriteXml( XclExpXmlStream& rWorkbookStrm ) // contents of XclExpChangeTrack::WriteUserNamesStream()). rWorkbookStrm.PushStream( pRevisionHeaders ); - std::vector<ExcRecord*>::iterator pIter; - for ( pIter = aRecList.begin(); pIter != aRecList.end(); ++pIter ) - (*pIter)->SaveXml(rWorkbookStrm); + RecListType::iterator pIter; + for (pIter = maRecList.begin(); pIter != maRecList.end(); ++pIter) + pIter->SaveXml(rWorkbookStrm); rWorkbookStrm.PopStream(); } |