1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sot/storage.hxx>
22 #include "XclExpChangeTrack.hxx"
23 #include "xeformula.hxx"
24 #include "formulacell.hxx"
25 #include "xcl97rec.hxx"
26 #include "document.hxx"
27 #include "editutil.hxx"
29 #include <oox/token/tokens.hxx>
30 #include <rtl/strbuf.hxx>
31 #include <svl/sharedstring.hxx>
35 static OString
lcl_GuidToOString( sal_uInt8 aGuid
[ 16 ] )
38 snprintf( sBuf
, sizeof( sBuf
),
39 "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
40 aGuid
[ 0 ], aGuid
[ 1 ], aGuid
[ 2 ], aGuid
[ 3 ], aGuid
[ 4 ], aGuid
[ 5 ], aGuid
[ 6 ], aGuid
[ 7 ],
41 aGuid
[ 8 ], aGuid
[ 9 ], aGuid
[ 10 ], aGuid
[ 11 ], aGuid
[ 12 ], aGuid
[ 13 ], aGuid
[ 14 ], aGuid
[ 15 ] );
42 return OString( sBuf
);
45 static OString
lcl_DateTimeToOString( const DateTime
& rDateTime
)
48 snprintf( sBuf
, sizeof( sBuf
),
49 "%d-%02d-%02dT%02d:%02d:%02d.%09" SAL_PRIuUINT32
"Z",
50 rDateTime
.GetYear(), rDateTime
.GetMonth(), rDateTime
.GetDay(),
51 rDateTime
.GetHour(), rDateTime
.GetMin(), rDateTime
.GetSec(),
52 rDateTime
.GetNanoSec() );
53 return OString( sBuf
);
58 static void lcl_WriteDateTime( XclExpStream
& rStrm
, const DateTime
& rDateTime
)
60 rStrm
.SetSliceSize( 7 );
61 rStrm
<< (sal_uInt16
) rDateTime
.GetYear()
62 << (sal_uInt8
) rDateTime
.GetMonth()
63 << (sal_uInt8
) rDateTime
.GetDay()
64 << (sal_uInt8
) rDateTime
.GetHour()
65 << (sal_uInt8
) rDateTime
.GetMin()
66 << (sal_uInt8
) rDateTime
.GetSec();
67 rStrm
.SetSliceSize( 0 );
70 // write string and fill rest of <nLength> with zero bytes
71 // <nLength> is without string header
72 static void lcl_WriteFixedString( XclExpStream
& rStrm
, const XclExpString
& rString
, sal_Size nLength
)
74 sal_Size nStrBytes
= rString
.GetBufferSize();
75 OSL_ENSURE( nLength
>= nStrBytes
, "lcl_WriteFixedString - String too long" );
76 if( rString
.Len() > 0 )
78 if( nLength
> nStrBytes
)
79 rStrm
.WriteZeroBytes( nLength
- nStrBytes
);
82 static inline void lcl_GenerateGUID( sal_uInt8
* pGUID
, bool& rValidGUID
)
84 rtl_createUuid( pGUID
, rValidGUID
? pGUID
: NULL
, false );
88 static inline void lcl_WriteGUID( XclExpStream
& rStrm
, const sal_uInt8
* pGUID
)
90 rStrm
.SetSliceSize( 16 );
91 for( sal_Size nIndex
= 0; nIndex
< 16; nIndex
++ )
92 rStrm
<< pGUID
[ nIndex
];
93 rStrm
.SetSliceSize( 0 );
96 XclExpUserBView::XclExpUserBView( const OUString
& rUsername
, const sal_uInt8
* pGUID
) :
97 sUsername( rUsername
)
99 memcpy( aGUID
, pGUID
, 16 );
102 void XclExpUserBView::SaveCont( XclExpStream
& rStrm
)
104 rStrm
<< (sal_uInt32
) 0xFF078014
105 << (sal_uInt32
) 0x00000001;
106 lcl_WriteGUID( rStrm
, aGUID
);
107 rStrm
.WriteZeroBytes( 8 );
108 rStrm
<< (sal_uInt32
) 1200
111 << (sal_uInt16
) 0x0CF7
112 << (sal_uInt16
) 0x0000
113 << (sal_uInt16
) 0x0001
114 << (sal_uInt16
) 0x0000;
115 if( sUsername
.Len() > 0 )
119 sal_uInt16
XclExpUserBView::GetNum() const
124 sal_Size
XclExpUserBView::GetLen() const
126 return 50 + ((sUsername
.Len() > 0) ? sUsername
.GetSize() : 0);
129 XclExpUserBViewList::XclExpUserBViewList( const ScChangeTrack
& rChangeTrack
)
131 sal_uInt8 aGUID
[ 16 ];
132 bool bValidGUID
= false;
133 const std::set
<OUString
>& rStrColl
= rChangeTrack
.GetUserCollection();
134 aViews
.reserve(rStrColl
.size());
135 std::set
<OUString
>::const_iterator it
= rStrColl
.begin(), itEnd
= rStrColl
.end();
136 for (; it
!= itEnd
; ++it
)
138 lcl_GenerateGUID( aGUID
, bValidGUID
);
139 aViews
.push_back( new XclExpUserBView(*it
, aGUID
) );
143 XclExpUserBViewList::~XclExpUserBViewList()
145 for( iterator iter
= aViews
.begin(); iter
!= aViews
.end(); ++iter
)
149 void XclExpUserBViewList::Save( XclExpStream
& rStrm
)
151 for( iterator iter
= aViews
.begin(); iter
!= aViews
.end(); ++iter
)
152 (*iter
)->Save( rStrm
);
155 XclExpUsersViewBegin::XclExpUsersViewBegin( const sal_uInt8
* pGUID
, sal_uInt32 nTab
) :
158 memcpy( aGUID
, pGUID
, 16 );
161 void XclExpUsersViewBegin::SaveCont( XclExpStream
& rStrm
)
163 lcl_WriteGUID( rStrm
, aGUID
);
168 << (sal_uInt32
) 0x0000003C
179 sal_uInt16
XclExpUsersViewBegin::GetNum() const
184 sal_Size
XclExpUsersViewBegin::GetLen() const
189 void XclExpUsersViewEnd::SaveCont( XclExpStream
& rStrm
)
191 rStrm
<< (sal_uInt16
) 0x0001;
194 sal_uInt16
XclExpUsersViewEnd::GetNum() const
199 sal_Size
XclExpUsersViewEnd::GetLen() const
204 void XclExpChTr0x0191::SaveCont( XclExpStream
& rStrm
)
206 rStrm
<< (sal_uInt16
) 0x0000;
209 sal_uInt16
XclExpChTr0x0191::GetNum() const
214 sal_Size
XclExpChTr0x0191::GetLen() const
219 void XclExpChTr0x0198::SaveCont( XclExpStream
& rStrm
)
221 rStrm
<< (sal_uInt16
) 0x0006
222 << (sal_uInt16
) 0x0000;
225 sal_uInt16
XclExpChTr0x0198::GetNum() const
230 sal_Size
XclExpChTr0x0198::GetLen() const
235 void XclExpChTr0x0192::SaveCont( XclExpStream
& rStrm
)
237 rStrm
<< sal_uInt16( 0x0022 );
238 rStrm
.WriteZeroBytes( 510 );
241 sal_uInt16
XclExpChTr0x0192::GetNum() const
246 sal_Size
XclExpChTr0x0192::GetLen() const
251 void XclExpChTr0x0197::SaveCont( XclExpStream
& rStrm
)
253 rStrm
<< (sal_uInt16
) 0x0000;
256 sal_uInt16
XclExpChTr0x0197::GetNum() const
261 sal_Size
XclExpChTr0x0197::GetLen() const
266 XclExpChTrEmpty::~XclExpChTrEmpty()
270 sal_uInt16
XclExpChTrEmpty::GetNum() const
275 sal_Size
XclExpChTrEmpty::GetLen() const
280 XclExpChTr0x0195::~XclExpChTr0x0195()
284 void XclExpChTr0x0195::SaveCont( XclExpStream
& rStrm
)
286 rStrm
.WriteZeroBytes( 162 );
289 sal_uInt16
XclExpChTr0x0195::GetNum() const
294 sal_Size
XclExpChTr0x0195::GetLen() const
299 XclExpChTr0x0194::~XclExpChTr0x0194()
303 void XclExpChTr0x0194::SaveCont( XclExpStream
& rStrm
)
305 rStrm
<< (sal_uInt32
) 0;
306 lcl_WriteDateTime( rStrm
, aDateTime
);
307 rStrm
<< (sal_uInt8
) 0;
308 lcl_WriteFixedString( rStrm
, sUsername
, 147 );
311 sal_uInt16
XclExpChTr0x0194::GetNum() const
316 sal_Size
XclExpChTr0x0194::GetLen() const
321 XclExpChTrHeader::~XclExpChTrHeader()
325 void XclExpChTrHeader::SaveCont( XclExpStream
& rStrm
)
327 rStrm
<< (sal_uInt16
) 0x0006
328 << (sal_uInt16
) 0x0000
329 << (sal_uInt16
) 0x000D;
330 lcl_WriteGUID( rStrm
, aGUID
);
331 lcl_WriteGUID( rStrm
, aGUID
);
333 << (sal_uInt16
) 0x0001
334 << (sal_uInt32
) 0x00000000
335 << (sal_uInt16
) 0x001E;
338 sal_uInt16
XclExpChTrHeader::GetNum() const
343 sal_Size
XclExpChTrHeader::GetLen() const
348 void XclExpChTrHeader::SaveXml( XclExpXmlStream
& rRevisionHeadersStrm
)
350 sax_fastparser::FSHelperPtr pHeaders
= rRevisionHeadersStrm
.GetCurrentStream();
351 rRevisionHeadersStrm
.WriteAttributes(
352 XML_guid
, lcl_GuidToOString( aGUID
).getStr(),
353 XML_lastGuid
, NULL
, // OOXTODO
354 XML_shared
, NULL
, // OOXTODO
355 XML_diskRevisions
, NULL
, // OOXTODO
356 XML_history
, NULL
, // OOXTODO
357 XML_trackRevisions
, NULL
, // OOXTODO
358 XML_exclusive
, NULL
, // OOXTODO
359 XML_revisionId
, NULL
, // OOXTODO
360 XML_version
, NULL
, // OOXTODO
361 XML_keepChangeHistory
, NULL
, // OOXTODO
362 XML_protected
, NULL
, // OOXTODO
363 XML_preserveHistory
, NULL
, // OOXTODO
365 pHeaders
->write( ">" );
368 void XclExpXmlChTrHeaders::SetGUID( const sal_uInt8
* pGUID
)
370 memcpy(maGUID
, pGUID
, 16);
373 void XclExpXmlChTrHeaders::SaveXml( XclExpXmlStream
& rStrm
)
375 sax_fastparser::FSHelperPtr pHeaders
= rStrm
.GetCurrentStream();
377 pHeaders
->write("<")->writeId(XML_headers
);
379 rStrm
.WriteAttributes(
380 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
381 FSNS(XML_xmlns
, XML_r
), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
382 XML_guid
, lcl_GuidToOString(maGUID
).getStr(),
383 XML_lastGuid
, NULL
, // OOXTODO
384 XML_shared
, NULL
, // OOXTODO
385 XML_diskRevisions
, NULL
, // OOXTODO
386 XML_history
, NULL
, // OOXTODO
387 XML_trackRevisions
, NULL
, // OOXTODO
388 XML_exclusive
, NULL
, // OOXTODO
389 XML_revisionId
, NULL
, // OOXTODO
390 XML_version
, NULL
, // OOXTODO
391 XML_keepChangeHistory
, NULL
, // OOXTODO
392 XML_protected
, NULL
, // OOXTODO
393 XML_preserveHistory
, NULL
, // OOXTODO
396 pHeaders
->write(">");
399 XclExpXmlChTrHeader::XclExpXmlChTrHeader(
400 const OUString
& rUserName
, const DateTime
& rDateTime
, const sal_uInt8
* pGUID
,
401 sal_Int32 nLogNumber
, const XclExpChTrTabIdBuffer
& rBuf
) :
402 maUserName(rUserName
), maDateTime(rDateTime
), mnLogNumber(nLogNumber
),
403 mnMinAction(0), mnMaxAction(0)
405 memcpy(maGUID
, pGUID
, 16);
406 if (rBuf
.GetBufferCount())
408 maTabBuffer
.resize(rBuf
.GetBufferCount());
409 rBuf
.GetBufferCopy(&maTabBuffer
[0]);
413 void XclExpXmlChTrHeader::SaveXml( XclExpXmlStream
& rStrm
)
415 sax_fastparser::FSHelperPtr pHeader
= rStrm
.GetCurrentStream();
417 pHeader
->write("<")->writeId(XML_header
);
420 sax_fastparser::FSHelperPtr pRevLogStrm
= rStrm
.CreateOutputStream(
421 XclXmlUtils::GetStreamName("xl/revisions/", "revisionLog", mnLogNumber
),
422 XclXmlUtils::GetStreamName(NULL
, "revisionLog", mnLogNumber
),
423 rStrm
.GetCurrentStream()->getOutputStream(),
424 "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml",
425 CREATE_OFFICEDOC_RELATION_TYPE("revisionLog"),
428 rStrm
.WriteAttributes(
429 XML_guid
, lcl_GuidToOString(maGUID
).getStr(),
430 XML_dateTime
, lcl_DateTimeToOString(maDateTime
).getStr(),
431 XML_userName
, XclXmlUtils::ToOString(maUserName
).getStr(),
432 FSNS(XML_r
, XML_id
), XclXmlUtils::ToOString(aRelId
).getStr(),
436 rStrm
.WriteAttributes(XML_minRId
, OString::number(mnMinAction
).getStr(), FSEND
);
439 rStrm
.WriteAttributes(XML_maxRId
, OString::number(mnMaxAction
).getStr(), FSEND
);
441 if (!maTabBuffer
.empty())
442 // next available sheet index.
443 rStrm
.WriteAttributes(XML_maxSheetId
, OString::number(maTabBuffer
.back()+1).getStr(), FSEND
);
447 if (!maTabBuffer
.empty())
449 // Write sheet index map.
450 size_t n
= maTabBuffer
.size();
451 pHeader
->startElement(
453 XML_count
, OString::number(n
).getStr(),
456 for (size_t i
= 0; i
< n
; ++i
)
458 pHeader
->singleElement(
460 XML_val
, OString::number(maTabBuffer
[i
]).getStr(),
463 pHeader
->endElement(XML_sheetIdMap
);
466 // Write all revision logs in a separate stream.
468 rStrm
.PushStream(pRevLogStrm
);
470 pRevLogStrm
->write("<")->writeId(XML_revisions
);
472 rStrm
.WriteAttributes(
473 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
474 FSNS(XML_xmlns
, XML_r
), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
477 pRevLogStrm
->write(">");
479 std::vector
<XclExpChTrAction
*>::iterator it
= maActions
.begin(), itEnd
= maActions
.end();
480 for (; it
!= itEnd
; ++it
)
482 XclExpChTrAction
* p
= *it
;
486 pRevLogStrm
->write("</")->writeId(XML_revisions
)->write(">");
490 pHeader
->write("</")->writeId(XML_header
)->write(">");
493 void XclExpXmlChTrHeader::AppendAction( XclExpChTrAction
* pAction
)
495 sal_uInt32 nActionNum
= pAction
->GetActionNumber();
496 if (!mnMinAction
|| mnMinAction
> nActionNum
)
497 mnMinAction
= nActionNum
;
499 if (!mnMaxAction
|| mnMaxAction
< nActionNum
)
500 mnMaxAction
= nActionNum
;
502 maActions
.push_back(pAction
);
505 XclExpChTrInfo::XclExpChTrInfo( const OUString
& rUsername
, const DateTime
& rDateTime
, const sal_uInt8
* pGUID
) :
506 sUsername( rUsername
),
507 aDateTime( rDateTime
)
509 memcpy( aGUID
, pGUID
, 16 );
512 XclExpChTrInfo::~XclExpChTrInfo()
516 void XclExpChTrInfo::SaveCont( XclExpStream
& rStrm
)
518 rStrm
<< (sal_uInt32
) 0xFFFFFFFF
519 << (sal_uInt32
) 0x00000000
520 << (sal_uInt32
) 0x00000020
521 << (sal_uInt16
) 0xFFFF;
522 lcl_WriteGUID( rStrm
, aGUID
);
523 rStrm
<< (sal_uInt16
) 0x04B0;
524 lcl_WriteFixedString( rStrm
, sUsername
, 113 );
525 lcl_WriteDateTime( rStrm
, aDateTime
);
526 rStrm
<< (sal_uInt8
) 0x0000
527 << (sal_uInt16
) 0x0002;
530 sal_uInt16
XclExpChTrInfo::GetNum() const
535 sal_Size
XclExpChTrInfo::GetLen() const
540 XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount
) :
544 pBuffer
= new sal_uInt16
[ nBufSize
];
545 memset( pBuffer
, 0, sizeof(sal_uInt16
) * nBufSize
);
546 pLast
= pBuffer
+ nBufSize
- 1;
549 XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer
& rCopy
) :
550 nBufSize( rCopy
.nBufSize
),
551 nLastId( rCopy
.nLastId
)
553 pBuffer
= new sal_uInt16
[ nBufSize
];
554 memcpy( pBuffer
, rCopy
.pBuffer
, sizeof(sal_uInt16
) * nBufSize
);
555 pLast
= pBuffer
+ nBufSize
- 1;
558 XclExpChTrTabIdBuffer::~XclExpChTrTabIdBuffer()
563 void XclExpChTrTabIdBuffer::InitFill( sal_uInt16 nIndex
)
565 OSL_ENSURE( nIndex
< nLastId
, "XclExpChTrTabIdBuffer::Insert - out of range" );
567 sal_uInt16 nFreeCount
= 0;
568 for( sal_uInt16
* pElem
= pBuffer
; pElem
<= pLast
; pElem
++ )
572 if( nFreeCount
> nIndex
)
580 void XclExpChTrTabIdBuffer::InitFillup()
582 sal_uInt16 nFreeCount
= 1;
583 for( sal_uInt16
* pElem
= pBuffer
; pElem
<= pLast
; pElem
++ )
585 *pElem
= nFreeCount
++;
589 sal_uInt16
XclExpChTrTabIdBuffer::GetId( sal_uInt16 nIndex
) const
591 OSL_ENSURE( nIndex
< nBufSize
, "XclExpChTrTabIdBuffer::GetId - out of range" );
592 return pBuffer
[ nIndex
];
595 void XclExpChTrTabIdBuffer::Remove()
597 OSL_ENSURE( pBuffer
<= pLast
, "XclExpChTrTabIdBuffer::Remove - buffer empty" );
598 sal_uInt16
* pElem
= pBuffer
;
599 while( (pElem
<= pLast
) && (*pElem
!= nLastId
) )
601 while( pElem
< pLast
)
603 *pElem
= *(pElem
+ 1);
610 XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer
& rBuffer
)
611 : nTabCount( rBuffer
.GetBufferCount() )
613 pBuffer
= new sal_uInt16
[ nTabCount
];
614 rBuffer
.GetBufferCopy( pBuffer
);
617 XclExpChTrTabId::~XclExpChTrTabId()
622 void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer
& rBuffer
)
625 nTabCount
= rBuffer
.GetBufferCount();
626 pBuffer
= new sal_uInt16
[ nTabCount
];
627 rBuffer
.GetBufferCopy( pBuffer
);
630 void XclExpChTrTabId::SaveCont( XclExpStream
& rStrm
)
632 rStrm
.EnableEncryption();
634 for( sal_uInt16
* pElem
= pBuffer
; pElem
< (pBuffer
+ nTabCount
); pElem
++ )
637 for( sal_uInt16 nIndex
= 1; nIndex
<= nTabCount
; nIndex
++ )
641 sal_uInt16
XclExpChTrTabId::GetNum() const
646 sal_Size
XclExpChTrTabId::GetLen() const
648 return nTabCount
<< 1;
651 // ! does not copy additional actions
652 XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction
& rCopy
) :
654 sUsername( rCopy
.sUsername
),
655 aDateTime( rCopy
.aDateTime
),
658 bAccepted( rCopy
.bAccepted
),
659 rTabInfo( rCopy
.rTabInfo
),
660 rIdBuffer( rCopy
.rIdBuffer
),
661 nLength( rCopy
.nLength
),
662 nOpCode( rCopy
.nOpCode
),
663 bForceInfo( rCopy
.bForceInfo
)
667 XclExpChTrAction::XclExpChTrAction(
668 const ScChangeAction
& rAction
,
669 const XclExpRoot
& rRoot
,
670 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
671 sal_uInt16 nNewOpCode
) :
672 sUsername( rAction
.GetUser() ),
673 aDateTime( rAction
.GetDateTime() ),
676 bAccepted( rAction
.IsAccepted() ),
677 rTabInfo( rRoot
.GetTabInfo() ),
678 rIdBuffer( rTabIdBuffer
),
680 nOpCode( nNewOpCode
),
683 aDateTime
.SetSec( 0 );
684 aDateTime
.SetNanoSec( 0 );
687 XclExpChTrAction::~XclExpChTrAction()
692 void XclExpChTrAction::SetAddAction( XclExpChTrAction
* pAction
)
695 pAddAction
->SetAddAction( pAction
);
697 pAddAction
= pAction
;
700 void XclExpChTrAction::AddDependentContents(
701 const ScChangeAction
& rAction
,
702 const XclExpRoot
& rRoot
,
703 ScChangeTrack
& rChangeTrack
)
705 ScChangeActionMap aActionMap
;
706 ScChangeActionMap::iterator itChangeAction
;
708 rChangeTrack
.GetDependents( const_cast<ScChangeAction
*>(&rAction
), aActionMap
);
709 for( itChangeAction
= aActionMap
.begin(); itChangeAction
!= aActionMap
.end(); ++itChangeAction
)
710 if( itChangeAction
->second
->GetType() == SC_CAT_CONTENT
)
711 SetAddAction( new XclExpChTrCellContent(
712 *static_cast<const ScChangeActionContent
*>(itChangeAction
->second
), rRoot
, rIdBuffer
) );
715 void XclExpChTrAction::SetIndex( sal_uInt32
& rIndex
)
720 void XclExpChTrAction::SaveCont( XclExpStream
& rStrm
)
722 OSL_ENSURE( nOpCode
!= EXC_CHTR_OP_UNKNOWN
, "XclExpChTrAction::SaveCont - unknown action" );
726 << (sal_uInt16
)(bAccepted
? EXC_CHTR_ACCEPT
: EXC_CHTR_NOTHING
);
727 SaveActionData( rStrm
);
730 void XclExpChTrAction::PrepareSaveAction( XclExpStream
& /*rStrm*/ ) const
734 void XclExpChTrAction::CompleteSaveAction( XclExpStream
& /*rStrm*/ ) const
738 void XclExpChTrAction::Save( XclExpStream
& rStrm
)
740 PrepareSaveAction( rStrm
);
741 ExcRecord::Save( rStrm
);
743 pAddAction
->Save( rStrm
);
744 CompleteSaveAction( rStrm
);
747 sal_Size
XclExpChTrAction::GetLen() const
749 return GetHeaderByteCount() + GetActionByteCount();
752 XclExpChTrData::XclExpChTrData() :
754 mpFormulaCell( NULL
),
757 nType( EXC_CHTR_TYPE_EMPTY
),
762 XclExpChTrData::~XclExpChTrData()
767 void XclExpChTrData::Clear()
770 mpFormulaCell
= NULL
;
775 nType
= EXC_CHTR_TYPE_EMPTY
;
779 void XclExpChTrData::WriteFormula( XclExpStream
& rStrm
, const XclExpChTrTabIdBuffer
& rTabIdBuffer
)
781 OSL_ENSURE( mxTokArr
&& !mxTokArr
->Empty(), "XclExpChTrData::Write - no formula" );
784 for( XclExpRefLog::const_iterator aIt
= maRefLog
.begin(), aEnd
= maRefLog
.end(); aIt
!= aEnd
; ++aIt
)
786 if( aIt
->mpUrl
&& aIt
->mpFirstTab
)
788 rStrm
<< *aIt
->mpUrl
<< (sal_uInt8
) 0x01 << *aIt
->mpFirstTab
<< (sal_uInt8
) 0x02;
792 bool bSingleTab
= aIt
->mnFirstXclTab
== aIt
->mnLastXclTab
;
793 rStrm
.SetSliceSize( bSingleTab
? 6 : 8 );
794 rStrm
<< (sal_uInt8
) 0x01 << (sal_uInt8
) 0x02 << (sal_uInt8
) 0x00;
795 rStrm
<< rTabIdBuffer
.GetId( aIt
->mnFirstXclTab
);
797 rStrm
<< (sal_uInt8
) 0x02;
799 rStrm
<< (sal_uInt8
) 0x00 << rTabIdBuffer
.GetId( aIt
->mnLastXclTab
);
802 rStrm
.SetSliceSize( 0 );
803 rStrm
<< (sal_uInt8
) 0x00;
806 void XclExpChTrData::Write( XclExpStream
& rStrm
, const XclExpChTrTabIdBuffer
& rTabIdBuffer
)
810 case EXC_CHTR_TYPE_RK
:
813 case EXC_CHTR_TYPE_DOUBLE
:
816 case EXC_CHTR_TYPE_STRING
:
817 OSL_ENSURE( pString
, "XclExpChTrData::Write - no string" );
820 case EXC_CHTR_TYPE_FORMULA
:
821 WriteFormula( rStrm
, rTabIdBuffer
);
826 XclExpChTrCellContent::XclExpChTrCellContent(
827 const ScChangeActionContent
& rAction
,
828 const XclExpRoot
& rRoot
,
829 const XclExpChTrTabIdBuffer
& rTabIdBuffer
) :
830 XclExpChTrAction( rAction
, rRoot
, rTabIdBuffer
, EXC_CHTR_OP_CELL
),
834 aPosition( rAction
.GetBigRange().MakeRange().aStart
)
838 GetCellData( rRoot
, rAction
.GetOldCell(), pOldData
, nDummy32
, nOldLength
);
839 GetCellData( rRoot
, rAction
.GetNewCell(), pNewData
, nLength
, nDummy16
);
842 XclExpChTrCellContent::~XclExpChTrCellContent()
848 void XclExpChTrCellContent::MakeEmptyChTrData( XclExpChTrData
*& rpData
)
853 rpData
= new XclExpChTrData
;
856 void XclExpChTrCellContent::GetCellData(
857 const XclExpRoot
& rRoot
, const ScCellValue
& rScCell
,
858 XclExpChTrData
*& rpData
, sal_uInt32
& rXclLength1
, sal_uInt16
& rXclLength2
)
860 MakeEmptyChTrData( rpData
);
861 rXclLength1
= 0x0000003A;
862 rXclLength2
= 0x0000;
864 if (rScCell
.isEmpty())
871 switch (rScCell
.meType
)
875 rpData
->fValue
= rScCell
.mfValue
;
876 if( XclTools::GetRKFromDouble( rpData
->nRKValue
, rpData
->fValue
) )
878 rpData
->nType
= EXC_CHTR_TYPE_RK
;
880 rXclLength1
= 0x0000003E;
881 rXclLength2
= 0x0004;
885 rpData
->nType
= EXC_CHTR_TYPE_DOUBLE
;
887 rXclLength1
= 0x00000042;
888 rXclLength2
= 0x0008;
892 case CELLTYPE_STRING
:
896 if (rScCell
.meType
== CELLTYPE_STRING
)
898 sCellStr
= rScCell
.mpString
->getString();
899 rpData
->mpFormattedString
= XclExpStringHelper::CreateCellString(
900 rRoot
, sCellStr
, NULL
);
904 XclExpHyperlinkHelper
aLinkHelper( rRoot
, aPosition
);
905 if (rScCell
.mpEditText
)
907 sCellStr
= ScEditUtil::GetString(*rScCell
.mpEditText
, &GetDoc());
908 rpData
->mpFormattedString
= XclExpStringHelper::CreateCellString(
909 rRoot
, *rScCell
.mpEditText
, NULL
, aLinkHelper
);
913 rpData
->mpFormattedString
= XclExpStringHelper::CreateCellString(
914 rRoot
, EMPTY_OUSTRING
, NULL
);
917 rpData
->pString
= new XclExpString( sCellStr
, EXC_STR_DEFAULT
, 32766 );
918 rpData
->nType
= EXC_CHTR_TYPE_STRING
;
919 rpData
->nSize
= 3 + rpData
->pString
->GetSize();
920 rXclLength1
= 64 + (sCellStr
.getLength() << 1);
921 rXclLength2
= 6 + (sal_uInt16
)(sCellStr
.getLength() << 1);
924 case CELLTYPE_FORMULA
:
926 const ScFormulaCell
* pFmlCell
= rScCell
.mpFormula
;
927 rpData
->mpFormulaCell
= pFmlCell
;
929 const ScTokenArray
* pTokenArray
= pFmlCell
->GetCode();
932 XclExpRefLog
& rRefLog
= rpData
->maRefLog
;
933 rpData
->mxTokArr
= GetFormulaCompiler().CreateFormula(
934 EXC_FMLATYPE_CELL
, *pTokenArray
, &pFmlCell
->aPos
, &rRefLog
);
935 rpData
->nType
= EXC_CHTR_TYPE_FORMULA
;
936 sal_Size nSize
= rpData
->mxTokArr
->GetSize() + 3;
938 for( XclExpRefLog::const_iterator aIt
= rRefLog
.begin(), aEnd
= rRefLog
.end(); aIt
!= aEnd
; ++aIt
)
940 if( aIt
->mpUrl
&& aIt
->mpFirstTab
)
941 nSize
+= aIt
->mpUrl
->GetSize() + aIt
->mpFirstTab
->GetSize() + 2;
943 nSize
+= (aIt
->mnFirstXclTab
== aIt
->mnLastXclTab
) ? 6 : 8;
945 rpData
->nSize
= ::std::min
< sal_Size
>( nSize
, 0xFFFF );
946 rXclLength1
= 0x00000052;
947 rXclLength2
= 0x0018;
955 void XclExpChTrCellContent::SaveActionData( XclExpStream
& rStrm
) const
957 WriteTabId( rStrm
, aPosition
.Tab() );
958 rStrm
<< (sal_uInt16
)((pOldData
? (pOldData
->nType
<< 3) : 0x0000) | (pNewData
? pNewData
->nType
: 0x0000))
959 << (sal_uInt16
) 0x0000;
960 Write2DAddress( rStrm
, aPosition
);
962 << (sal_uInt32
) 0x00000000;
964 pOldData
->Write( rStrm
, rIdBuffer
);
966 pNewData
->Write( rStrm
, rIdBuffer
);
969 sal_uInt16
XclExpChTrCellContent::GetNum() const
974 sal_Size
XclExpChTrCellContent::GetActionByteCount() const
978 nLen
+= pOldData
->nSize
;
980 nLen
+= pNewData
->nSize
;
984 static const char* lcl_GetType( XclExpChTrData
* pData
)
986 switch( pData
->nType
)
988 case EXC_CHTR_TYPE_RK
:
989 case EXC_CHTR_TYPE_DOUBLE
:
992 case EXC_CHTR_TYPE_FORMULA
:
994 ScFormulaCell
* pFormulaCell
= const_cast< ScFormulaCell
* >( pData
->mpFormulaCell
);
997 XclXmlUtils::GetFormulaTypeAndValue( *pFormulaCell
, sType
, sValue
);
1001 case EXC_CHTR_TYPE_STRING
:
1010 static void lcl_WriteCell( XclExpXmlStream
& rStrm
, sal_Int32 nElement
, const ScAddress
& rPosition
, XclExpChTrData
* pData
)
1012 sax_fastparser::FSHelperPtr pStream
= rStrm
.GetCurrentStream();
1014 pStream
->startElement( nElement
,
1015 XML_r
, XclXmlUtils::ToOString( rPosition
).getStr(),
1016 XML_s
, NULL
, // OOXTODO: not supported
1017 XML_t
, lcl_GetType( pData
),
1018 XML_cm
, NULL
, // OOXTODO: not supported
1019 XML_vm
, NULL
, // OOXTODO: not supported
1020 XML_ph
, NULL
, // OOXTODO: not supported
1022 switch( pData
->nType
)
1024 case EXC_CHTR_TYPE_RK
:
1025 case EXC_CHTR_TYPE_DOUBLE
:
1026 pStream
->startElement( XML_v
, FSEND
);
1027 pStream
->write( pData
->fValue
);
1028 pStream
->endElement( XML_v
);
1030 case EXC_CHTR_TYPE_FORMULA
:
1031 pStream
->startElement( XML_f
,
1032 // OOXTODO: other attributes? see XclExpFormulaCell::SaveXml()
1034 pStream
->writeEscaped( XclXmlUtils::ToOUString(
1035 rStrm
.GetRoot().GetCompileFormulaContext(),
1036 pData
->mpFormulaCell
->aPos
, pData
->mpFormulaCell
->GetCode()));
1037 pStream
->endElement( XML_f
);
1039 case EXC_CHTR_TYPE_STRING
:
1040 pStream
->startElement( XML_is
, FSEND
);
1041 if( pData
->mpFormattedString
)
1042 pData
->mpFormattedString
->WriteXml( rStrm
);
1044 pData
->pString
->WriteXml( rStrm
);
1045 pStream
->endElement( XML_is
);
1051 pStream
->endElement( nElement
);
1054 void XclExpChTrCellContent::SaveXml( XclExpXmlStream
& rRevisionLogStrm
)
1056 sax_fastparser::FSHelperPtr pStream
= rRevisionLogStrm
.GetCurrentStream();
1057 pStream
->startElement( XML_rcc
,
1058 XML_rId
, OString::number( GetActionNumber() ).getStr(),
1059 XML_ua
, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
1060 XML_ra
, NULL
, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
1061 XML_sId
, OString::number( GetTabId( aPosition
.Tab() ) ).getStr(),
1062 XML_odxf
, NULL
, // OOXTODO: not supported
1063 XML_xfDxf
, NULL
, // OOXTODO: not supported
1064 XML_s
, NULL
, // OOXTODO: not supported
1065 XML_dxf
, NULL
, // OOXTODO: not supported
1066 XML_numFmtId
, NULL
, // OOXTODO: not supported
1067 XML_quotePrefix
, NULL
, // OOXTODO: not supported
1068 XML_oldQuotePrefix
, NULL
, // OOXTODO: not supported
1069 XML_ph
, NULL
, // OOXTODO: not supported
1070 XML_oldPh
, NULL
, // OOXTODO: not supported
1071 XML_endOfListFormulaUpdate
, NULL
, // OOXTODO: not supported
1075 lcl_WriteCell( rRevisionLogStrm
, XML_oc
, aPosition
, pOldData
);
1078 pStream
->singleElement(XML_nc
,
1079 XML_r
, XclXmlUtils::ToOString( aPosition
).getStr(),
1085 lcl_WriteCell( rRevisionLogStrm
, XML_nc
, aPosition
, pNewData
);
1087 // OOXTODO: XML_odxf, XML_ndxf, XML_extLst elements
1088 pStream
->endElement( XML_rcc
);
1091 XclExpChTrInsert::XclExpChTrInsert( const XclExpChTrInsert
& rCopy
) :
1092 XclExpChTrAction(rCopy
),
1093 mbEndOfList(rCopy
.mbEndOfList
),
1094 aRange(rCopy
.aRange
) {}
1096 XclExpChTrInsert::XclExpChTrInsert(
1097 const ScChangeAction
& rAction
,
1098 const XclExpRoot
& rRoot
,
1099 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
1100 ScChangeTrack
& rChangeTrack
) :
1101 XclExpChTrAction( rAction
, rRoot
, rTabIdBuffer
),
1103 aRange( rAction
.GetBigRange().MakeRange() )
1105 nLength
= 0x00000030;
1106 switch( rAction
.GetType() )
1108 case SC_CAT_INSERT_COLS
: nOpCode
= EXC_CHTR_OP_INSCOL
; break;
1109 case SC_CAT_INSERT_ROWS
:
1111 const ScChangeActionIns
& rIns
= static_cast<const ScChangeActionIns
&>(rAction
);
1112 mbEndOfList
= rIns
.IsEndOfList();
1113 nOpCode
= EXC_CHTR_OP_INSROW
;
1116 case SC_CAT_DELETE_COLS
: nOpCode
= EXC_CHTR_OP_DELCOL
; break;
1117 case SC_CAT_DELETE_ROWS
: nOpCode
= EXC_CHTR_OP_DELROW
; break;
1119 OSL_FAIL( "XclExpChTrInsert::XclExpChTrInsert - unknown action" );
1122 if( nOpCode
& EXC_CHTR_OP_COLFLAG
)
1124 aRange
.aStart
.SetRow( 0 );
1125 aRange
.aEnd
.SetRow( rRoot
.GetXclMaxPos().Row() );
1129 aRange
.aStart
.SetCol( 0 );
1130 aRange
.aEnd
.SetCol( rRoot
.GetXclMaxPos().Col() );
1133 if( nOpCode
& EXC_CHTR_OP_DELFLAG
)
1135 SetAddAction( new XclExpChTr0x014A( *this ) );
1136 AddDependentContents( rAction
, rRoot
, rChangeTrack
);
1140 XclExpChTrInsert::~XclExpChTrInsert()
1144 void XclExpChTrInsert::SaveActionData( XclExpStream
& rStrm
) const
1146 WriteTabId( rStrm
, aRange
.aStart
.Tab() );
1147 sal_uInt16 nFlagVal
= mbEndOfList
? 0x0001 : 0x0000;
1149 Write2DRange( rStrm
, aRange
);
1150 rStrm
<< (sal_uInt32
) 0x00000000;
1153 void XclExpChTrInsert::PrepareSaveAction( XclExpStream
& rStrm
) const
1155 if( (nOpCode
== EXC_CHTR_OP_DELROW
) || (nOpCode
== EXC_CHTR_OP_DELCOL
) )
1156 XclExpChTrEmpty( 0x0150 ).Save( rStrm
);
1159 void XclExpChTrInsert::CompleteSaveAction( XclExpStream
& rStrm
) const
1161 if( (nOpCode
== EXC_CHTR_OP_DELROW
) || (nOpCode
== EXC_CHTR_OP_DELCOL
) )
1162 XclExpChTrEmpty( 0x0151 ).Save( rStrm
);
1165 sal_uInt16
XclExpChTrInsert::GetNum() const
1170 sal_Size
XclExpChTrInsert::GetActionByteCount() const
1175 static const char* lcl_GetAction( sal_uInt16 nOpCode
)
1179 case EXC_CHTR_OP_INSCOL
: return "insertCol";
1180 case EXC_CHTR_OP_INSROW
: return "insertRow";
1181 case EXC_CHTR_OP_DELCOL
: return "deleteCol";
1182 case EXC_CHTR_OP_DELROW
: return "deleteRow";
1183 default: return "*unknown*";
1187 void XclExpChTrInsert::SaveXml( XclExpXmlStream
& rRevisionLogStrm
)
1189 sax_fastparser::FSHelperPtr pStream
= rRevisionLogStrm
.GetCurrentStream();
1190 pStream
->startElement( XML_rrc
,
1191 XML_rId
, OString::number( GetActionNumber() ).getStr(),
1192 XML_ua
, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
1193 XML_ra
, NULL
, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
1194 XML_sId
, OString::number( GetTabId( aRange
.aStart
.Tab() ) ).getStr(),
1195 XML_eol
, XclXmlUtils::ToPsz10(mbEndOfList
),
1196 XML_ref
, XclXmlUtils::ToOString( aRange
).getStr(),
1197 XML_action
, lcl_GetAction( nOpCode
),
1198 XML_edge
, NULL
, // OOXTODO: ???
1201 // OOXTODO: does this handle XML_rfmt, XML_undo?
1202 XclExpChTrAction
* pAction
= GetAddAction();
1203 while( pAction
!= NULL
)
1205 pAction
->SaveXml( rRevisionLogStrm
);
1206 pAction
= pAction
->GetAddAction();
1208 pStream
->endElement( XML_rrc
);
1211 XclExpChTrInsertTab::XclExpChTrInsertTab(
1212 const ScChangeAction
& rAction
,
1213 const XclExpRoot
& rRoot
,
1214 const XclExpChTrTabIdBuffer
& rTabIdBuffer
) :
1215 XclExpChTrAction( rAction
, rRoot
, rTabIdBuffer
, EXC_CHTR_OP_INSTAB
),
1216 XclExpRoot( rRoot
),
1217 nTab( (SCTAB
) rAction
.GetBigRange().aStart
.Tab() )
1219 nLength
= 0x0000021C;
1223 XclExpChTrInsertTab::~XclExpChTrInsertTab()
1227 void XclExpChTrInsertTab::SaveActionData( XclExpStream
& rStrm
) const
1229 WriteTabId( rStrm
, nTab
);
1230 rStrm
<< sal_uInt32( 0 );
1231 lcl_WriteFixedString( rStrm
, XclExpString( GetTabInfo().GetScTabName( nTab
) ), 127 );
1232 lcl_WriteDateTime( rStrm
, GetDateTime() );
1233 rStrm
.WriteZeroBytes( 133 );
1236 sal_uInt16
XclExpChTrInsertTab::GetNum() const
1241 sal_Size
XclExpChTrInsertTab::GetActionByteCount() const
1246 void XclExpChTrInsertTab::SaveXml( XclExpXmlStream
& rStrm
)
1248 sax_fastparser::FSHelperPtr pStream
= rStrm
.GetCurrentStream();
1249 pStream
->singleElement( XML_ris
,
1250 XML_rId
, OString::number( GetActionNumber() ).getStr(),
1251 XML_ua
, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
1252 XML_ra
, NULL
, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
1253 XML_sheetId
, OString::number( GetTabId( nTab
) ).getStr(),
1254 XML_name
, XclXmlUtils::ToOString( GetTabInfo().GetScTabName( nTab
) ).getStr(),
1255 XML_sheetPosition
, OString::number( nTab
).getStr(),
1259 XclExpChTrMoveRange::XclExpChTrMoveRange(
1260 const ScChangeActionMove
& rAction
,
1261 const XclExpRoot
& rRoot
,
1262 const XclExpChTrTabIdBuffer
& rTabIdBuffer
,
1263 ScChangeTrack
& rChangeTrack
) :
1264 XclExpChTrAction( rAction
, rRoot
, rTabIdBuffer
, EXC_CHTR_OP_MOVE
),
1265 aDestRange( rAction
.GetBigRange().MakeRange() )
1267 nLength
= 0x00000042;
1268 aSourceRange
= aDestRange
;
1269 sal_Int32 nDCols
, nDRows
, nDTabs
;
1270 rAction
.GetDelta( nDCols
, nDRows
, nDTabs
);
1271 aSourceRange
.aStart
.IncRow( (SCROW
) -nDRows
);
1272 aSourceRange
.aStart
.IncCol( (SCCOL
) -nDCols
);
1273 aSourceRange
.aStart
.IncTab( (SCTAB
) -nDTabs
);
1274 aSourceRange
.aEnd
.IncRow( (SCROW
) -nDRows
);
1275 aSourceRange
.aEnd
.IncCol( (SCCOL
) -nDCols
);
1276 aSourceRange
.aEnd
.IncTab( (SCTAB
) -nDTabs
);
1277 AddDependentContents( rAction
, rRoot
, rChangeTrack
);
1280 XclExpChTrMoveRange::~XclExpChTrMoveRange()
1284 void XclExpChTrMoveRange::SaveActionData( XclExpStream
& rStrm
) const
1286 WriteTabId( rStrm
, aDestRange
.aStart
.Tab() );
1287 Write2DRange( rStrm
, aSourceRange
);
1288 Write2DRange( rStrm
, aDestRange
);
1289 WriteTabId( rStrm
, aSourceRange
.aStart
.Tab() );
1290 rStrm
<< (sal_uInt32
) 0x00000000;
1293 void XclExpChTrMoveRange::PrepareSaveAction( XclExpStream
& rStrm
) const
1295 XclExpChTrEmpty( 0x014E ).Save( rStrm
);
1298 void XclExpChTrMoveRange::CompleteSaveAction( XclExpStream
& rStrm
) const
1300 XclExpChTrEmpty( 0x014F ).Save( rStrm
);
1303 sal_uInt16
XclExpChTrMoveRange::GetNum() const
1308 sal_Size
XclExpChTrMoveRange::GetActionByteCount() const
1313 void XclExpChTrMoveRange::SaveXml( XclExpXmlStream
& rRevisionLogStrm
)
1315 sax_fastparser::FSHelperPtr pStream
= rRevisionLogStrm
.GetCurrentStream();
1317 pStream
->startElement( XML_rm
,
1318 XML_rId
, OString::number( GetActionNumber() ).getStr(),
1319 XML_ua
, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
1320 XML_ra
, NULL
, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
1321 XML_sheetId
, OString::number( GetTabId( aDestRange
.aStart
.Tab() ) ).getStr(),
1322 XML_source
, XclXmlUtils::ToOString( aSourceRange
).getStr(),
1323 XML_destination
, XclXmlUtils::ToOString( aDestRange
).getStr(),
1324 XML_sourceSheetId
, OString::number( GetTabId( aSourceRange
.aStart
.Tab() ) ).getStr(),
1326 // OOXTODO: does this handle XML_rfmt, XML_undo?
1327 XclExpChTrAction
* pAction
= GetAddAction();
1328 while( pAction
!= NULL
)
1330 pAction
->SaveXml( rRevisionLogStrm
);
1331 pAction
= pAction
->GetAddAction();
1333 pStream
->endElement( XML_rm
);
1336 XclExpChTr0x014A::XclExpChTr0x014A( const XclExpChTrInsert
& rAction
) :
1337 XclExpChTrInsert( rAction
)
1339 nLength
= 0x00000026;
1340 nOpCode
= EXC_CHTR_OP_FORMAT
;
1343 XclExpChTr0x014A::~XclExpChTr0x014A()
1347 void XclExpChTr0x014A::SaveActionData( XclExpStream
& rStrm
) const
1349 WriteTabId( rStrm
, aRange
.aStart
.Tab() );
1350 rStrm
<< (sal_uInt16
) 0x0003
1351 << (sal_uInt16
) 0x0001;
1352 Write2DRange( rStrm
, aRange
);
1355 sal_uInt16
XclExpChTr0x014A::GetNum() const
1360 sal_Size
XclExpChTr0x014A::GetActionByteCount() const
1365 void XclExpChTr0x014A::SaveXml( XclExpXmlStream
& rStrm
)
1367 sax_fastparser::FSHelperPtr pStream
= rStrm
.GetCurrentStream();
1369 pStream
->startElement( XML_rfmt
,
1370 XML_sheetId
, OString::number( GetTabId( aRange
.aStart
.Tab() ) ).getStr(),
1371 XML_xfDxf
, NULL
, // OOXTODO: not supported
1372 XML_s
, NULL
, // OOXTODO: style
1373 XML_sqref
, XclXmlUtils::ToOString( aRange
).getStr(),
1374 XML_start
, NULL
, // OOXTODO: for string changes
1375 XML_length
, NULL
, // OOXTODO: for string changes
1377 // OOXTODO: XML_dxf, XML_extLst
1379 pStream
->endElement( XML_rfmt
);
1382 sal_Size
ExcXmlRecord::GetLen() const
1387 sal_uInt16
ExcXmlRecord::GetNum() const
1392 void ExcXmlRecord::Save( XclExpStream
& )
1394 // Do nothing; ignored for BIFF output.
1397 class EndXmlElement
: public ExcXmlRecord
1399 sal_Int32 mnElement
;
1401 EndXmlElement( sal_Int32 nElement
) : mnElement( nElement
) {}
1402 virtual void SaveXml( XclExpXmlStream
& rStrm
) SAL_OVERRIDE
;
1405 void EndXmlElement::SaveXml( XclExpXmlStream
& rStrm
)
1407 sax_fastparser::FSHelperPtr pStream
= rStrm
.GetCurrentStream();
1408 pStream
->write("</")->writeId(mnElement
)->write(">");
1411 XclExpChangeTrack::XclExpChangeTrack( const XclExpRoot
& rRoot
) :
1412 XclExpRoot( rRoot
),
1414 pTabIdBuffer( NULL
),
1419 OSL_ENSURE( GetOldRoot().pTabId
, "XclExpChangeTrack::XclExpChangeTrack - root data incomplete" );
1420 if( !GetOldRoot().pTabId
)
1423 ScChangeTrack
* pTempChangeTrack
= CreateTempChangeTrack();
1424 if (!pTempChangeTrack
)
1427 pTabIdBuffer
= new XclExpChTrTabIdBuffer( GetTabInfo().GetXclTabCount() );
1428 maBuffers
.push_back( pTabIdBuffer
);
1430 // calculate final table order (tab id list)
1431 const ScChangeAction
* pScAction
;
1432 for( pScAction
= pTempChangeTrack
->GetLast(); pScAction
; pScAction
= pScAction
->GetPrev() )
1434 if( pScAction
->GetType() == SC_CAT_INSERT_TABS
)
1436 SCTAB nScTab
= static_cast< SCTAB
>( pScAction
->GetBigRange().aStart
.Tab() );
1437 pTabIdBuffer
->InitFill( GetTabInfo().GetXclTab( nScTab
) );
1440 pTabIdBuffer
->InitFillup();
1441 GetOldRoot().pTabId
->Copy( *pTabIdBuffer
);
1443 // get actions in reverse order
1444 pScAction
= pTempChangeTrack
->GetLast();
1447 PushActionRecord( *pScAction
);
1448 const ScChangeAction
* pPrevAction
= pScAction
->GetPrev();
1449 pScAction
= pPrevAction
;
1452 // build record list
1453 if (GetOutput() == EXC_OUTPUT_BINARY
)
1455 pHeader
= new XclExpChTrHeader
;
1456 maRecList
.push_back( pHeader
);
1457 maRecList
.push_back( new XclExpChTr0x0195
);
1458 maRecList
.push_back( new XclExpChTr0x0194( *pTempChangeTrack
) );
1460 OUString sLastUsername
;
1461 DateTime
aLastDateTime( DateTime::EMPTY
);
1462 sal_uInt32 nIndex
= 1;
1463 sal_Int32 nLogNumber
= 1;
1464 while( !aActionStack
.empty() )
1466 XclExpChTrAction
* pAction
= aActionStack
.top();
1469 if( (nIndex
== 1) || pAction
->ForceInfoRecord() ||
1470 (pAction
->GetUsername() != sLastUsername
) ||
1471 (pAction
->GetDateTime() != aLastDateTime
) )
1473 lcl_GenerateGUID( aGUID
, bValidGUID
);
1474 sLastUsername
= pAction
->GetUsername();
1475 aLastDateTime
= pAction
->GetDateTime();
1478 maRecList
.push_back( new XclExpChTrInfo(sLastUsername
, aLastDateTime
, aGUID
) );
1479 maRecList
.push_back( new XclExpChTrTabId(pAction
->GetTabIdBuffer()) );
1480 pHeader
->SetGUID( aGUID
);
1482 pAction
->SetIndex( nIndex
);
1483 maRecList
.push_back( pAction
);
1486 pHeader
->SetGUID( aGUID
);
1487 pHeader
->SetCount( nIndex
- 1 );
1488 maRecList
.push_back( new ExcEof
);
1492 XclExpXmlChTrHeaders
* pHeaders
= new XclExpXmlChTrHeaders
;
1493 maRecList
.push_back(pHeaders
);
1495 OUString sLastUsername
;
1496 DateTime
aLastDateTime(DateTime::EMPTY
);
1497 sal_uInt32 nIndex
= 1;
1498 sal_Int32 nLogNumber
= 1;
1499 XclExpXmlChTrHeader
* pCurHeader
= NULL
;
1501 while (!aActionStack
.empty())
1503 XclExpChTrAction
* pAction
= aActionStack
.top();
1506 if( (nIndex
== 1) || pAction
->ForceInfoRecord() ||
1507 (pAction
->GetUsername() != sLastUsername
) ||
1508 (pAction
->GetDateTime() != aLastDateTime
) )
1510 lcl_GenerateGUID( aGUID
, bValidGUID
);
1511 sLastUsername
= pAction
->GetUsername();
1512 aLastDateTime
= pAction
->GetDateTime();
1514 pCurHeader
= new XclExpXmlChTrHeader(sLastUsername
, aLastDateTime
, aGUID
, nLogNumber
, pAction
->GetTabIdBuffer());
1515 maRecList
.push_back(pCurHeader
);
1517 pHeaders
->SetGUID(aGUID
);
1519 pAction
->SetIndex(nIndex
);
1520 pCurHeader
->AppendAction(pAction
);
1523 pHeaders
->SetGUID(aGUID
);
1524 maRecList
.push_back(new EndXmlElement(XML_headers
));
1528 XclExpChangeTrack::~XclExpChangeTrack()
1530 while( !aActionStack
.empty() )
1532 delete aActionStack
.top();
1539 ScChangeTrack
* XclExpChangeTrack::CreateTempChangeTrack()
1541 // get original change track
1542 ScChangeTrack
* pOrigChangeTrack
= GetDoc().GetChangeTrack();
1543 OSL_ENSURE( pOrigChangeTrack
, "XclExpChangeTrack::CreateTempChangeTrack - no change track data" );
1544 if( !pOrigChangeTrack
)
1547 // create empty document
1548 pTempDoc
= new ScDocument
;
1550 // adjust table count
1551 SCTAB nOrigCount
= GetDoc().GetTableCount();
1553 for( sal_Int32 nIndex
= 0; nIndex
< nOrigCount
; nIndex
++ )
1555 pTempDoc
->CreateValidTabName( sTabName
);
1556 pTempDoc
->InsertTab( SC_TAB_APPEND
, sTabName
);
1558 OSL_ENSURE( nOrigCount
== pTempDoc
->GetTableCount(),
1559 "XclExpChangeTrack::CreateTempChangeTrack - table count mismatch" );
1560 if( nOrigCount
!= pTempDoc
->GetTableCount() )
1563 return pOrigChangeTrack
->Clone(pTempDoc
);
1566 void XclExpChangeTrack::PushActionRecord( const ScChangeAction
& rAction
)
1568 XclExpChTrAction
* pXclAction
= NULL
;
1569 ScChangeTrack
* pTempChangeTrack
= pTempDoc
->GetChangeTrack();
1570 switch( rAction
.GetType() )
1572 case SC_CAT_CONTENT
:
1573 pXclAction
= new XclExpChTrCellContent( static_cast<const ScChangeActionContent
&>(rAction
), GetRoot(), *pTabIdBuffer
);
1575 case SC_CAT_INSERT_ROWS
:
1576 case SC_CAT_INSERT_COLS
:
1577 case SC_CAT_DELETE_ROWS
:
1578 case SC_CAT_DELETE_COLS
:
1579 if (pTempChangeTrack
)
1580 pXclAction
= new XclExpChTrInsert( rAction
, GetRoot(), *pTabIdBuffer
, *pTempChangeTrack
);
1582 case SC_CAT_INSERT_TABS
:
1584 pXclAction
= new XclExpChTrInsertTab( rAction
, GetRoot(), *pTabIdBuffer
);
1585 XclExpChTrTabIdBuffer
* pNewBuffer
= new XclExpChTrTabIdBuffer( *pTabIdBuffer
);
1586 pNewBuffer
->Remove();
1587 maBuffers
.push_back( pNewBuffer
);
1588 pTabIdBuffer
= pNewBuffer
;
1592 if (pTempChangeTrack
)
1593 pXclAction
= new XclExpChTrMoveRange( static_cast<const ScChangeActionMove
&>(rAction
), GetRoot(), *pTabIdBuffer
, *pTempChangeTrack
);
1598 aActionStack
.push( pXclAction
);
1601 bool XclExpChangeTrack::WriteUserNamesStream()
1604 tools::SvRef
<SotStorageStream
> xSvStrm
= OpenStream( EXC_STREAM_USERNAMES
);
1605 OSL_ENSURE( xSvStrm
.Is(), "XclExpChangeTrack::WriteUserNamesStream - no stream" );
1608 XclExpStream
aXclStrm( *xSvStrm
, GetRoot() );
1609 XclExpChTr0x0191().Save( aXclStrm
);
1610 XclExpChTr0x0198().Save( aXclStrm
);
1611 XclExpChTr0x0192().Save( aXclStrm
);
1612 XclExpChTr0x0197().Save( aXclStrm
);
1619 void XclExpChangeTrack::Write()
1621 if (maRecList
.empty())
1624 if( WriteUserNamesStream() )
1626 tools::SvRef
<SotStorageStream
> xSvStrm
= OpenStream( EXC_STREAM_REVLOG
);
1627 OSL_ENSURE( xSvStrm
.Is(), "XclExpChangeTrack::Write - no stream" );
1630 XclExpStream
aXclStrm( *xSvStrm
, GetRoot(), EXC_MAXRECSIZE_BIFF8
+ 8 );
1632 RecListType::iterator pIter
;
1633 for (pIter
= maRecList
.begin(); pIter
!= maRecList
.end(); ++pIter
)
1634 pIter
->Save(aXclStrm
);
1641 static void lcl_WriteUserNamesXml( XclExpXmlStream
& rWorkbookStrm
)
1643 sax_fastparser::FSHelperPtr pUserNames
= rWorkbookStrm
.CreateOutputStream(
1644 OUString( "xl/revisions/userNames.xml" ),
1645 OUString( "revisions/userNames.xml" ),
1646 rWorkbookStrm
.GetCurrentStream()->getOutputStream(),
1647 "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml",
1648 CREATE_OFFICEDOC_RELATION_TYPE("usernames"));
1649 pUserNames
->startElement( XML_users
,
1650 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1651 FSNS( XML_xmlns
, XML_r
), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
1654 // OOXTODO: XML_userinfo elements for each user editing the file
1655 // Doesn't seem to be supported by .xls output either (based on
1656 // contents of XclExpChangeTrack::WriteUserNamesStream()).
1657 pUserNames
->endElement( XML_users
);
1660 void XclExpChangeTrack::WriteXml( XclExpXmlStream
& rWorkbookStrm
)
1662 if (maRecList
.empty())
1665 lcl_WriteUserNamesXml( rWorkbookStrm
);
1667 sax_fastparser::FSHelperPtr pRevisionHeaders
= rWorkbookStrm
.CreateOutputStream(
1668 OUString( "xl/revisions/revisionHeaders.xml" ),
1669 OUString( "revisions/revisionHeaders.xml" ),
1670 rWorkbookStrm
.GetCurrentStream()->getOutputStream(),
1671 "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml",
1672 CREATE_OFFICEDOC_RELATION_TYPE("revisionHeaders"));
1673 // OOXTODO: XML_userinfo elements for each user editing the file
1674 // Doesn't seem to be supported by .xls output either (based on
1675 // contents of XclExpChangeTrack::WriteUserNamesStream()).
1676 rWorkbookStrm
.PushStream( pRevisionHeaders
);
1678 RecListType::iterator pIter
;
1679 for (pIter
= maRecList
.begin(); pIter
!= maRecList
.end(); ++pIter
)
1680 pIter
->SaveXml(rWorkbookStrm
);
1682 rWorkbookStrm
.PopStream();
1685 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */