fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / filter / xcl97 / XclExpChangeTrack.cxx
blobacd7fa2cb33fd83a831e52695f0fc89429f415b6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <stdio.h>
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>
33 using namespace oox;
35 static OString lcl_GuidToOString( sal_uInt8 aGuid[ 16 ] )
37 char sBuf[ 40 ];
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 )
47 char sBuf[ 200 ];
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 );
56 // local functions
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 )
77 rStrm << rString;
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 );
85 rValidGUID = true;
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
109 << (sal_uInt32) 1000
110 << (sal_uInt16) 1000
111 << (sal_uInt16) 0x0CF7
112 << (sal_uInt16) 0x0000
113 << (sal_uInt16) 0x0001
114 << (sal_uInt16) 0x0000;
115 if( sUsername.Len() > 0 )
116 rStrm << sUsername;
119 sal_uInt16 XclExpUserBView::GetNum() const
121 return 0x01A9;
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 )
146 delete *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 ) :
156 nCurrTab( nTab )
158 memcpy( aGUID, pGUID, 16 );
161 void XclExpUsersViewBegin::SaveCont( XclExpStream& rStrm )
163 lcl_WriteGUID( rStrm, aGUID );
164 rStrm << nCurrTab
165 << (sal_uInt32) 100
166 << (sal_uInt32) 64
167 << (sal_uInt32) 3
168 << (sal_uInt32) 0x0000003C
169 << (sal_uInt16) 0
170 << (sal_uInt16) 3
171 << (sal_uInt16) 0
172 << (sal_uInt16) 3
173 << (double) 0
174 << (double) 0
175 << (sal_Int16) -1
176 << (sal_Int16) -1;
179 sal_uInt16 XclExpUsersViewBegin::GetNum() const
181 return 0x01AA;
184 sal_Size XclExpUsersViewBegin::GetLen() const
186 return 64;
189 void XclExpUsersViewEnd::SaveCont( XclExpStream& rStrm )
191 rStrm << (sal_uInt16) 0x0001;
194 sal_uInt16 XclExpUsersViewEnd::GetNum() const
196 return 0x01AB;
199 sal_Size XclExpUsersViewEnd::GetLen() const
201 return 2;
204 void XclExpChTr0x0191::SaveCont( XclExpStream& rStrm )
206 rStrm << (sal_uInt16) 0x0000;
209 sal_uInt16 XclExpChTr0x0191::GetNum() const
211 return 0x0191;
214 sal_Size XclExpChTr0x0191::GetLen() const
216 return 2;
219 void XclExpChTr0x0198::SaveCont( XclExpStream& rStrm )
221 rStrm << (sal_uInt16) 0x0006
222 << (sal_uInt16) 0x0000;
225 sal_uInt16 XclExpChTr0x0198::GetNum() const
227 return 0x0198;
230 sal_Size XclExpChTr0x0198::GetLen() const
232 return 4;
235 void XclExpChTr0x0192::SaveCont( XclExpStream& rStrm )
237 rStrm << sal_uInt16( 0x0022 );
238 rStrm.WriteZeroBytes( 510 );
241 sal_uInt16 XclExpChTr0x0192::GetNum() const
243 return 0x0192;
246 sal_Size XclExpChTr0x0192::GetLen() const
248 return 512;
251 void XclExpChTr0x0197::SaveCont( XclExpStream& rStrm )
253 rStrm << (sal_uInt16) 0x0000;
256 sal_uInt16 XclExpChTr0x0197::GetNum() const
258 return 0x0197;
261 sal_Size XclExpChTr0x0197::GetLen() const
263 return 2;
266 XclExpChTrEmpty::~XclExpChTrEmpty()
270 sal_uInt16 XclExpChTrEmpty::GetNum() const
272 return nRecNum;
275 sal_Size XclExpChTrEmpty::GetLen() const
277 return 0;
280 XclExpChTr0x0195::~XclExpChTr0x0195()
284 void XclExpChTr0x0195::SaveCont( XclExpStream& rStrm )
286 rStrm.WriteZeroBytes( 162 );
289 sal_uInt16 XclExpChTr0x0195::GetNum() const
291 return 0x0195;
294 sal_Size XclExpChTr0x0195::GetLen() const
296 return 162;
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
313 return 0x0194;
316 sal_Size XclExpChTr0x0194::GetLen() const
318 return 162;
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 );
332 rStrm << nCount
333 << (sal_uInt16) 0x0001
334 << (sal_uInt32) 0x00000000
335 << (sal_uInt16) 0x001E;
338 sal_uInt16 XclExpChTrHeader::GetNum() const
340 return 0x0196;
343 sal_Size XclExpChTrHeader::GetLen() const
345 return 50;
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
364 FSEND );
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
394 FSEND);
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);
419 OUString aRelId;
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"),
426 &aRelId);
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(),
433 FSEND);
435 if (mnMinAction)
436 rStrm.WriteAttributes(XML_minRId, OString::number(mnMinAction).getStr(), FSEND);
438 if (mnMaxAction)
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);
445 pHeader->write(">");
447 if (!maTabBuffer.empty())
449 // Write sheet index map.
450 size_t n = maTabBuffer.size();
451 pHeader->startElement(
452 XML_sheetIdMap,
453 XML_count, OString::number(n).getStr(),
454 FSEND);
456 for (size_t i = 0; i < n; ++i)
458 pHeader->singleElement(
459 XML_sheetId,
460 XML_val, OString::number(maTabBuffer[i]).getStr(),
461 FSEND);
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",
475 FSEND);
477 pRevLogStrm->write(">");
479 std::vector<XclExpChTrAction*>::iterator it = maActions.begin(), itEnd = maActions.end();
480 for (; it != itEnd; ++it)
482 XclExpChTrAction* p = *it;
483 p->SaveXml(rStrm);
486 pRevLogStrm->write("</")->writeId(XML_revisions)->write(">");
488 rStrm.PopStream();
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
532 return 0x0138;
535 sal_Size XclExpChTrInfo::GetLen() const
537 return 158;
540 XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount ) :
541 nBufSize( nCount ),
542 nLastId( 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()
560 delete[] pBuffer;
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++ )
570 if( !*pElem )
571 nFreeCount++;
572 if( nFreeCount > nIndex )
574 *pElem = nLastId--;
575 return;
580 void XclExpChTrTabIdBuffer::InitFillup()
582 sal_uInt16 nFreeCount = 1;
583 for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
584 if( !*pElem )
585 *pElem = nFreeCount++;
586 nLastId = nBufSize;
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) )
600 pElem++;
601 while( pElem < pLast )
603 *pElem = *(pElem + 1);
604 pElem++;
606 pLast--;
607 nLastId--;
610 XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer )
611 : nTabCount( rBuffer.GetBufferCount() )
613 pBuffer = new sal_uInt16[ nTabCount ];
614 rBuffer.GetBufferCopy( pBuffer );
617 XclExpChTrTabId::~XclExpChTrTabId()
619 Clear();
622 void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer& rBuffer )
624 Clear();
625 nTabCount = rBuffer.GetBufferCount();
626 pBuffer = new sal_uInt16[ nTabCount ];
627 rBuffer.GetBufferCopy( pBuffer );
630 void XclExpChTrTabId::SaveCont( XclExpStream& rStrm )
632 rStrm.EnableEncryption();
633 if( pBuffer )
634 for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ )
635 rStrm << *pElem;
636 else
637 for( sal_uInt16 nIndex = 1; nIndex <= nTabCount; nIndex++ )
638 rStrm << nIndex;
641 sal_uInt16 XclExpChTrTabId::GetNum() const
643 return 0x013D;
646 sal_Size XclExpChTrTabId::GetLen() const
648 return nTabCount << 1;
651 // ! does not copy additional actions
652 XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction& rCopy ) :
653 ExcRecord( rCopy ),
654 sUsername( rCopy.sUsername ),
655 aDateTime( rCopy.aDateTime ),
656 nIndex( 0 ),
657 pAddAction( 0 ),
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() ),
674 nIndex( 0 ),
675 pAddAction( NULL ),
676 bAccepted( rAction.IsAccepted() ),
677 rTabInfo( rRoot.GetTabInfo() ),
678 rIdBuffer( rTabIdBuffer ),
679 nLength( 0 ),
680 nOpCode( nNewOpCode ),
681 bForceInfo( false )
683 aDateTime.SetSec( 0 );
684 aDateTime.SetNanoSec( 0 );
687 XclExpChTrAction::~XclExpChTrAction()
689 delete pAddAction;
692 void XclExpChTrAction::SetAddAction( XclExpChTrAction* pAction )
694 if( pAddAction )
695 pAddAction->SetAddAction( pAction );
696 else
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 )
717 nIndex = rIndex++;
720 void XclExpChTrAction::SaveCont( XclExpStream& rStrm )
722 OSL_ENSURE( nOpCode != EXC_CHTR_OP_UNKNOWN, "XclExpChTrAction::SaveCont - unknown action" );
723 rStrm << nLength
724 << nIndex
725 << nOpCode
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 );
742 if( pAddAction )
743 pAddAction->Save( rStrm );
744 CompleteSaveAction( rStrm );
747 sal_Size XclExpChTrAction::GetLen() const
749 return GetHeaderByteCount() + GetActionByteCount();
752 XclExpChTrData::XclExpChTrData() :
753 pString( NULL ),
754 mpFormulaCell( NULL ),
755 fValue( 0.0 ),
756 nRKValue( 0 ),
757 nType( EXC_CHTR_TYPE_EMPTY ),
758 nSize( 0 )
762 XclExpChTrData::~XclExpChTrData()
764 Clear();
767 void XclExpChTrData::Clear()
769 DELETEZ( pString );
770 mpFormulaCell = NULL;
771 mxTokArr.reset();
772 maRefLog.clear();
773 fValue = 0.0;
774 nRKValue = 0;
775 nType = EXC_CHTR_TYPE_EMPTY;
776 nSize = 0;
779 void XclExpChTrData::WriteFormula( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
781 OSL_ENSURE( mxTokArr && !mxTokArr->Empty(), "XclExpChTrData::Write - no formula" );
782 rStrm << *mxTokArr;
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;
790 else
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 );
796 if( bSingleTab )
797 rStrm << (sal_uInt8) 0x02;
798 else
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 )
808 switch( nType )
810 case EXC_CHTR_TYPE_RK:
811 rStrm << nRKValue;
812 break;
813 case EXC_CHTR_TYPE_DOUBLE:
814 rStrm << fValue;
815 break;
816 case EXC_CHTR_TYPE_STRING:
817 OSL_ENSURE( pString, "XclExpChTrData::Write - no string" );
818 rStrm << *pString;
819 break;
820 case EXC_CHTR_TYPE_FORMULA:
821 WriteFormula( rStrm, rTabIdBuffer );
822 break;
826 XclExpChTrCellContent::XclExpChTrCellContent(
827 const ScChangeActionContent& rAction,
828 const XclExpRoot& rRoot,
829 const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
830 XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_CELL ),
831 XclExpRoot( rRoot ),
832 pOldData( 0 ),
833 pNewData( 0 ),
834 aPosition( rAction.GetBigRange().MakeRange().aStart )
836 sal_uInt32 nDummy32;
837 sal_uInt16 nDummy16;
838 GetCellData( rRoot, rAction.GetOldCell(), pOldData, nDummy32, nOldLength );
839 GetCellData( rRoot, rAction.GetNewCell(), pNewData, nLength, nDummy16 );
842 XclExpChTrCellContent::~XclExpChTrCellContent()
844 delete pOldData;
845 delete pNewData;
848 void XclExpChTrCellContent::MakeEmptyChTrData( XclExpChTrData*& rpData )
850 if( rpData )
851 rpData->Clear();
852 else
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())
866 delete rpData;
867 rpData = NULL;
868 return;
871 switch (rScCell.meType)
873 case CELLTYPE_VALUE:
875 rpData->fValue = rScCell.mfValue;
876 if( XclTools::GetRKFromDouble( rpData->nRKValue, rpData->fValue ) )
878 rpData->nType = EXC_CHTR_TYPE_RK;
879 rpData->nSize = 4;
880 rXclLength1 = 0x0000003E;
881 rXclLength2 = 0x0004;
883 else
885 rpData->nType = EXC_CHTR_TYPE_DOUBLE;
886 rpData->nSize = 8;
887 rXclLength1 = 0x00000042;
888 rXclLength2 = 0x0008;
891 break;
892 case CELLTYPE_STRING:
893 case CELLTYPE_EDIT:
895 OUString sCellStr;
896 if (rScCell.meType == CELLTYPE_STRING)
898 sCellStr = rScCell.mpString->getString();
899 rpData->mpFormattedString = XclExpStringHelper::CreateCellString(
900 rRoot, sCellStr, NULL);
902 else
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);
911 else
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);
923 break;
924 case CELLTYPE_FORMULA:
926 const ScFormulaCell* pFmlCell = rScCell.mpFormula;
927 rpData->mpFormulaCell = pFmlCell;
929 const ScTokenArray* pTokenArray = pFmlCell->GetCode();
930 if( pTokenArray )
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;
942 else
943 nSize += (aIt->mnFirstXclTab == aIt->mnLastXclTab) ? 6 : 8;
945 rpData->nSize = ::std::min< sal_Size >( nSize, 0xFFFF );
946 rXclLength1 = 0x00000052;
947 rXclLength2 = 0x0018;
950 break;
951 default:;
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 );
961 rStrm << nOldLength
962 << (sal_uInt32) 0x00000000;
963 if( pOldData )
964 pOldData->Write( rStrm, rIdBuffer );
965 if( pNewData )
966 pNewData->Write( rStrm, rIdBuffer );
969 sal_uInt16 XclExpChTrCellContent::GetNum() const
971 return 0x013B;
974 sal_Size XclExpChTrCellContent::GetActionByteCount() const
976 sal_Size nLen = 16;
977 if( pOldData )
978 nLen += pOldData->nSize;
979 if( pNewData )
980 nLen += pNewData->nSize;
981 return nLen;
984 static const char* lcl_GetType( XclExpChTrData* pData )
986 switch( pData->nType )
988 case EXC_CHTR_TYPE_RK:
989 case EXC_CHTR_TYPE_DOUBLE:
990 return "n";
991 break;
992 case EXC_CHTR_TYPE_FORMULA:
994 ScFormulaCell* pFormulaCell = const_cast< ScFormulaCell* >( pData->mpFormulaCell );
995 const char* sType;
996 OUString sValue;
997 XclXmlUtils::GetFormulaTypeAndValue( *pFormulaCell, sType, sValue );
998 return sType;
1000 break;
1001 case EXC_CHTR_TYPE_STRING:
1002 return "inlineStr";
1003 break;
1004 default:
1005 break;
1007 return "*unknown*";
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
1021 FSEND );
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 );
1029 break;
1030 case EXC_CHTR_TYPE_FORMULA:
1031 pStream->startElement( XML_f,
1032 // OOXTODO: other attributes? see XclExpFormulaCell::SaveXml()
1033 FSEND );
1034 pStream->writeEscaped( XclXmlUtils::ToOUString(
1035 rStrm.GetRoot().GetCompileFormulaContext(),
1036 pData->mpFormulaCell->aPos, pData->mpFormulaCell->GetCode()));
1037 pStream->endElement( XML_f );
1038 break;
1039 case EXC_CHTR_TYPE_STRING:
1040 pStream->startElement( XML_is, FSEND );
1041 if( pData->mpFormattedString )
1042 pData->mpFormattedString->WriteXml( rStrm );
1043 else
1044 pData->pString->WriteXml( rStrm );
1045 pStream->endElement( XML_is );
1046 break;
1047 default:
1048 // ignore
1049 break;
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
1072 FSEND );
1073 if( pOldData )
1075 lcl_WriteCell( rRevisionLogStrm, XML_oc, aPosition, pOldData );
1076 if (!pNewData)
1078 pStream->singleElement(XML_nc,
1079 XML_r, XclXmlUtils::ToOString( aPosition ).getStr(),
1080 FSEND);
1083 if( pNewData )
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 ),
1102 mbEndOfList(false),
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;
1115 break;
1116 case SC_CAT_DELETE_COLS: nOpCode = EXC_CHTR_OP_DELCOL; break;
1117 case SC_CAT_DELETE_ROWS: nOpCode = EXC_CHTR_OP_DELROW; break;
1118 default:
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() );
1127 else
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;
1148 rStrm << nFlagVal;
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
1167 return 0x0137;
1170 sal_Size XclExpChTrInsert::GetActionByteCount() const
1172 return 16;
1175 static const char* lcl_GetAction( sal_uInt16 nOpCode )
1177 switch( 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: ???
1199 FSEND );
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;
1220 bForceInfo = true;
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
1238 return 0x014D;
1241 sal_Size XclExpChTrInsertTab::GetActionByteCount() const
1243 return 276;
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(),
1256 FSEND );
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
1305 return 0x0140;
1308 sal_Size XclExpChTrMoveRange::GetActionByteCount() const
1310 return 24;
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(),
1325 FSEND );
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
1357 return 0x014A;
1360 sal_Size XclExpChTr0x014A::GetActionByteCount() const
1362 return 14;
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
1376 FSEND );
1377 // OOXTODO: XML_dxf, XML_extLst
1379 pStream->endElement( XML_rfmt );
1382 sal_Size ExcXmlRecord::GetLen() const
1384 return 0;
1387 sal_uInt16 ExcXmlRecord::GetNum() const
1389 return 0;
1392 void ExcXmlRecord::Save( XclExpStream& )
1394 // Do nothing; ignored for BIFF output.
1397 class EndXmlElement : public ExcXmlRecord
1399 sal_Int32 mnElement;
1400 public:
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 ),
1413 aActionStack(),
1414 pTabIdBuffer( NULL ),
1415 pTempDoc( NULL ),
1416 pHeader( NULL ),
1417 bValidGUID( false )
1419 OSL_ENSURE( GetOldRoot().pTabId, "XclExpChangeTrack::XclExpChangeTrack - root data incomplete" );
1420 if( !GetOldRoot().pTabId )
1421 return;
1423 ScChangeTrack* pTempChangeTrack = CreateTempChangeTrack();
1424 if (!pTempChangeTrack)
1425 return;
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();
1445 while( pScAction )
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();
1467 aActionStack.pop();
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();
1477 nLogNumber++;
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 );
1490 else
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();
1504 aActionStack.pop();
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);
1516 nLogNumber++;
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();
1533 aActionStack.pop();
1536 delete pTempDoc;
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 )
1545 return NULL;
1547 // create empty document
1548 pTempDoc = new ScDocument;
1550 // adjust table count
1551 SCTAB nOrigCount = GetDoc().GetTableCount();
1552 OUString sTabName;
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() )
1561 return NULL;
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 );
1574 break;
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 );
1581 break;
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;
1590 break;
1591 case SC_CAT_MOVE:
1592 if (pTempChangeTrack)
1593 pXclAction = new XclExpChTrMoveRange( static_cast<const ScChangeActionMove&>(rAction), GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
1594 break;
1595 default:;
1597 if( pXclAction )
1598 aActionStack.push( pXclAction );
1601 bool XclExpChangeTrack::WriteUserNamesStream()
1603 bool bRet = false;
1604 tools::SvRef<SotStorageStream> xSvStrm = OpenStream( EXC_STREAM_USERNAMES );
1605 OSL_ENSURE( xSvStrm.Is(), "XclExpChangeTrack::WriteUserNamesStream - no stream" );
1606 if( xSvStrm.Is() )
1608 XclExpStream aXclStrm( *xSvStrm, GetRoot() );
1609 XclExpChTr0x0191().Save( aXclStrm );
1610 XclExpChTr0x0198().Save( aXclStrm );
1611 XclExpChTr0x0192().Save( aXclStrm );
1612 XclExpChTr0x0197().Save( aXclStrm );
1613 xSvStrm->Commit();
1614 bRet = true;
1616 return bRet;
1619 void XclExpChangeTrack::Write()
1621 if (maRecList.empty())
1622 return;
1624 if( WriteUserNamesStream() )
1626 tools::SvRef<SotStorageStream> xSvStrm = OpenStream( EXC_STREAM_REVLOG );
1627 OSL_ENSURE( xSvStrm.Is(), "XclExpChangeTrack::Write - no stream" );
1628 if( xSvStrm.Is() )
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);
1636 xSvStrm->Commit();
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",
1652 XML_count, "0",
1653 FSEND );
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())
1663 return;
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: */