Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 :
22 : //___________________________________________________________________
23 :
24 : #include <stdio.h>
25 : #include <sot/storage.hxx>
26 : #include "XclExpChangeTrack.hxx"
27 : #include "xeformula.hxx"
28 : #include "cell.hxx"
29 : #include "xcl97rec.hxx"
30 :
31 : #include <oox/token/tokens.hxx>
32 : #include <rtl/strbuf.hxx>
33 :
34 : using ::rtl::OUString;
35 : using ::rtl::OString;
36 : using ::rtl::OStringBuffer;
37 : using namespace oox;
38 :
39 0 : static OString lcl_GuidToOString( sal_uInt8 aGuid[ 16 ] )
40 : {
41 : char sBuf[ 40 ];
42 : snprintf( sBuf, sizeof( sBuf ),
43 : "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
44 0 : aGuid[ 0 ], aGuid[ 1 ], aGuid[ 2 ], aGuid[ 3 ], aGuid[ 4 ], aGuid[ 5 ], aGuid[ 6 ], aGuid[ 7 ],
45 0 : aGuid[ 8 ], aGuid[ 9 ], aGuid[ 10 ], aGuid[ 11 ], aGuid[ 12 ], aGuid[ 13 ], aGuid[ 14 ], aGuid[ 15 ] );
46 0 : return OString( sBuf );
47 : }
48 :
49 0 : static OString lcl_DateTimeToOString( const DateTime& rDateTime )
50 : {
51 : char sBuf[ 200 ];
52 : snprintf( sBuf, sizeof( sBuf ),
53 : "%d-%02d-%02dT%02d:%02d:%02d.%02dZ",
54 0 : rDateTime.GetYear(), rDateTime.GetMonth(), rDateTime.GetDay(),
55 0 : rDateTime.GetHour(), rDateTime.GetMin(), rDateTime.GetSec(),
56 0 : rDateTime.Get100Sec() );
57 0 : return OString( sBuf );
58 : }
59 :
60 : //___________________________________________________________________
61 : // local functions
62 :
63 0 : static void lcl_WriteDateTime( XclExpStream& rStrm, const DateTime& rDateTime )
64 : {
65 0 : rStrm.SetSliceSize( 7 );
66 0 : rStrm << (sal_uInt16) rDateTime.GetYear()
67 0 : << (sal_uInt8) rDateTime.GetMonth()
68 0 : << (sal_uInt8) rDateTime.GetDay()
69 0 : << (sal_uInt8) rDateTime.GetHour()
70 0 : << (sal_uInt8) rDateTime.GetMin()
71 0 : << (sal_uInt8) rDateTime.GetSec();
72 0 : rStrm.SetSliceSize( 0 );
73 0 : }
74 :
75 : // write string and fill rest of <nLength> with zero bytes
76 : // <nLength> is without string header
77 0 : static void lcl_WriteFixedString( XclExpStream& rStrm, const XclExpString& rString, sal_Size nLength )
78 : {
79 0 : sal_Size nStrBytes = rString.GetBufferSize();
80 : OSL_ENSURE( nLength >= nStrBytes, "lcl_WriteFixedString - String too long" );
81 0 : if( rString.Len() > 0 )
82 0 : rStrm << rString;
83 0 : if( nLength > nStrBytes )
84 0 : rStrm.WriteZeroBytes( nLength - nStrBytes );
85 0 : }
86 :
87 0 : static inline void lcl_GenerateGUID( sal_uInt8* pGUID, sal_Bool& rValidGUID )
88 : {
89 0 : rtl_createUuid( pGUID, rValidGUID ? pGUID : NULL, false );
90 0 : rValidGUID = sal_True;
91 0 : }
92 :
93 0 : static inline void lcl_WriteGUID( XclExpStream& rStrm, const sal_uInt8* pGUID )
94 : {
95 0 : rStrm.SetSliceSize( 16 );
96 0 : for( sal_Size nIndex = 0; nIndex < 16; nIndex++ )
97 0 : rStrm << pGUID[ nIndex ];
98 0 : rStrm.SetSliceSize( 0 );
99 0 : }
100 :
101 : //___________________________________________________________________
102 :
103 0 : XclExpUserBView::XclExpUserBView( const String& rUsername, const sal_uInt8* pGUID ) :
104 0 : sUsername( rUsername )
105 : {
106 0 : memcpy( aGUID, pGUID, 16 );
107 0 : }
108 :
109 0 : void XclExpUserBView::SaveCont( XclExpStream& rStrm )
110 : {
111 0 : rStrm << (sal_uInt32) 0xFF078014
112 0 : << (sal_uInt32) 0x00000001;
113 0 : lcl_WriteGUID( rStrm, aGUID );
114 0 : rStrm.WriteZeroBytes( 8 );
115 0 : rStrm << (sal_uInt32) 1200
116 0 : << (sal_uInt32) 1000
117 0 : << (sal_uInt16) 1000
118 0 : << (sal_uInt16) 0x0CF7
119 0 : << (sal_uInt16) 0x0000
120 0 : << (sal_uInt16) 0x0001
121 0 : << (sal_uInt16) 0x0000;
122 0 : if( sUsername.Len() > 0 )
123 0 : rStrm << sUsername;
124 0 : }
125 :
126 0 : sal_uInt16 XclExpUserBView::GetNum() const
127 : {
128 0 : return 0x01A9;
129 : }
130 :
131 0 : sal_Size XclExpUserBView::GetLen() const
132 : {
133 0 : return 50 + ((sUsername.Len() > 0) ? sUsername.GetSize() : 0);
134 : }
135 :
136 : //___________________________________________________________________
137 :
138 0 : XclExpUserBViewList::XclExpUserBViewList( const ScChangeTrack& rChangeTrack )
139 : {
140 : sal_uInt8 aGUID[ 16 ];
141 0 : sal_Bool bValidGUID = false;
142 0 : const std::set<rtl::OUString>& rStrColl = rChangeTrack.GetUserCollection();
143 0 : aViews.reserve(rStrColl.size());
144 0 : std::set<rtl::OUString>::const_iterator it = rStrColl.begin(), itEnd = rStrColl.end();
145 0 : for (; it != itEnd; ++it)
146 : {
147 0 : lcl_GenerateGUID( aGUID, bValidGUID );
148 0 : aViews.push_back( new XclExpUserBView(*it, aGUID) );
149 : }
150 0 : }
151 :
152 0 : XclExpUserBViewList::~XclExpUserBViewList()
153 : {
154 0 : for( iterator iter = aViews.begin(); iter != aViews.end(); ++iter )
155 0 : delete *iter;
156 0 : }
157 :
158 0 : void XclExpUserBViewList::Save( XclExpStream& rStrm )
159 : {
160 0 : for( iterator iter = aViews.begin(); iter != aViews.end(); ++iter )
161 0 : (*iter)->Save( rStrm );
162 0 : }
163 :
164 : //___________________________________________________________________
165 :
166 0 : XclExpUsersViewBegin::XclExpUsersViewBegin( const sal_uInt8* pGUID, sal_uInt32 nTab ) :
167 0 : nCurrTab( nTab )
168 : {
169 0 : memcpy( aGUID, pGUID, 16 );
170 0 : }
171 :
172 0 : void XclExpUsersViewBegin::SaveCont( XclExpStream& rStrm )
173 : {
174 0 : lcl_WriteGUID( rStrm, aGUID );
175 0 : rStrm << nCurrTab
176 0 : << (sal_uInt32) 100
177 0 : << (sal_uInt32) 64
178 0 : << (sal_uInt32) 3
179 0 : << (sal_uInt32) 0x0000003C
180 0 : << (sal_uInt16) 0
181 0 : << (sal_uInt16) 3
182 0 : << (sal_uInt16) 0
183 0 : << (sal_uInt16) 3
184 0 : << (double) 0
185 0 : << (double) 0
186 0 : << (sal_Int16) -1
187 0 : << (sal_Int16) -1;
188 0 : }
189 :
190 0 : sal_uInt16 XclExpUsersViewBegin::GetNum() const
191 : {
192 0 : return 0x01AA;
193 : }
194 :
195 0 : sal_Size XclExpUsersViewBegin::GetLen() const
196 : {
197 0 : return 64;
198 : }
199 :
200 : //___________________________________________________________________
201 :
202 0 : void XclExpUsersViewEnd::SaveCont( XclExpStream& rStrm )
203 : {
204 0 : rStrm << (sal_uInt16) 0x0001;
205 0 : }
206 :
207 0 : sal_uInt16 XclExpUsersViewEnd::GetNum() const
208 : {
209 0 : return 0x01AB;
210 : }
211 :
212 0 : sal_Size XclExpUsersViewEnd::GetLen() const
213 : {
214 0 : return 2;
215 : }
216 :
217 : //___________________________________________________________________
218 :
219 0 : void XclExpChTr0x0191::SaveCont( XclExpStream& rStrm )
220 : {
221 0 : rStrm << (sal_uInt16) 0x0000;
222 0 : }
223 :
224 0 : sal_uInt16 XclExpChTr0x0191::GetNum() const
225 : {
226 0 : return 0x0191;
227 : }
228 :
229 0 : sal_Size XclExpChTr0x0191::GetLen() const
230 : {
231 0 : return 2;
232 : }
233 :
234 : //___________________________________________________________________
235 :
236 0 : void XclExpChTr0x0198::SaveCont( XclExpStream& rStrm )
237 : {
238 0 : rStrm << (sal_uInt16) 0x0006
239 0 : << (sal_uInt16) 0x0000;
240 0 : }
241 :
242 0 : sal_uInt16 XclExpChTr0x0198::GetNum() const
243 : {
244 0 : return 0x0198;
245 : }
246 :
247 0 : sal_Size XclExpChTr0x0198::GetLen() const
248 : {
249 0 : return 4;
250 : }
251 :
252 : //___________________________________________________________________
253 :
254 0 : void XclExpChTr0x0192::SaveCont( XclExpStream& rStrm )
255 : {
256 0 : rStrm << sal_uInt16( 0x0022 );
257 0 : rStrm.WriteZeroBytes( 510 );
258 0 : }
259 :
260 0 : sal_uInt16 XclExpChTr0x0192::GetNum() const
261 : {
262 0 : return 0x0192;
263 : }
264 :
265 0 : sal_Size XclExpChTr0x0192::GetLen() const
266 : {
267 0 : return 512;
268 : }
269 :
270 : //___________________________________________________________________
271 :
272 0 : void XclExpChTr0x0197::SaveCont( XclExpStream& rStrm )
273 : {
274 0 : rStrm << (sal_uInt16) 0x0000;
275 0 : }
276 :
277 0 : sal_uInt16 XclExpChTr0x0197::GetNum() const
278 : {
279 0 : return 0x0197;
280 : }
281 :
282 0 : sal_Size XclExpChTr0x0197::GetLen() const
283 : {
284 0 : return 2;
285 : }
286 :
287 : //___________________________________________________________________
288 :
289 0 : XclExpChTrEmpty::~XclExpChTrEmpty()
290 : {
291 0 : }
292 :
293 0 : sal_uInt16 XclExpChTrEmpty::GetNum() const
294 : {
295 0 : return nRecNum;
296 : }
297 :
298 0 : sal_Size XclExpChTrEmpty::GetLen() const
299 : {
300 0 : return 0;
301 : }
302 :
303 : //___________________________________________________________________
304 :
305 0 : XclExpChTr0x0195::~XclExpChTr0x0195()
306 : {
307 0 : }
308 :
309 0 : void XclExpChTr0x0195::SaveCont( XclExpStream& rStrm )
310 : {
311 0 : rStrm.WriteZeroBytes( 162 );
312 0 : }
313 :
314 0 : sal_uInt16 XclExpChTr0x0195::GetNum() const
315 : {
316 0 : return 0x0195;
317 : }
318 :
319 0 : sal_Size XclExpChTr0x0195::GetLen() const
320 : {
321 0 : return 162;
322 : }
323 :
324 : //___________________________________________________________________
325 :
326 0 : XclExpChTr0x0194::~XclExpChTr0x0194()
327 : {
328 0 : }
329 :
330 0 : void XclExpChTr0x0194::SaveCont( XclExpStream& rStrm )
331 : {
332 0 : rStrm << (sal_uInt32) 0;
333 0 : lcl_WriteDateTime( rStrm, aDateTime );
334 0 : rStrm << (sal_uInt8) 0;
335 0 : lcl_WriteFixedString( rStrm, sUsername, 147 );
336 0 : }
337 :
338 0 : sal_uInt16 XclExpChTr0x0194::GetNum() const
339 : {
340 0 : return 0x0194;
341 : }
342 :
343 0 : sal_Size XclExpChTr0x0194::GetLen() const
344 : {
345 0 : return 162;
346 : }
347 :
348 : //___________________________________________________________________
349 :
350 0 : XclExpChTrHeader::~XclExpChTrHeader()
351 : {
352 0 : }
353 :
354 0 : void XclExpChTrHeader::SaveCont( XclExpStream& rStrm )
355 : {
356 0 : rStrm << (sal_uInt16) 0x0006
357 0 : << (sal_uInt16) 0x0000
358 0 : << (sal_uInt16) 0x000D;
359 0 : lcl_WriteGUID( rStrm, aGUID );
360 0 : lcl_WriteGUID( rStrm, aGUID );
361 0 : rStrm << nCount
362 0 : << (sal_uInt16) 0x0001
363 0 : << (sal_uInt32) 0x00000000
364 0 : << (sal_uInt16) 0x001E;
365 0 : }
366 :
367 0 : sal_uInt16 XclExpChTrHeader::GetNum() const
368 : {
369 0 : return 0x0196;
370 : }
371 :
372 0 : sal_Size XclExpChTrHeader::GetLen() const
373 : {
374 0 : return 50;
375 : }
376 :
377 0 : void XclExpChTrHeader::SaveXml( XclExpXmlStream& rRevisionHeadersStrm )
378 : {
379 0 : sax_fastparser::FSHelperPtr pHeaders = rRevisionHeadersStrm.GetCurrentStream();
380 : rRevisionHeadersStrm.WriteAttributes(
381 : XML_guid, lcl_GuidToOString( aGUID ).getStr(),
382 : XML_lastGuid, NULL, // OOXTODO
383 : XML_shared, NULL, // OOXTODO
384 : XML_diskRevisions, NULL, // OOXTODO
385 : XML_history, NULL, // OOXTODO
386 : XML_trackRevisions, NULL, // OOXTODO
387 : XML_exclusive, NULL, // OOXTODO
388 : XML_revisionId, NULL, // OOXTODO
389 : XML_version, NULL, // OOXTODO
390 : XML_keepChangeHistory, NULL, // OOXTODO
391 : XML_protected, NULL, // OOXTODO
392 : XML_preserveHistory, NULL, // OOXTODO
393 0 : FSEND );
394 0 : pHeaders->write( ">" );
395 0 : }
396 :
397 : //___________________________________________________________________
398 :
399 0 : XclExpChTrInfo::~XclExpChTrInfo()
400 : {
401 0 : }
402 :
403 0 : void XclExpChTrInfo::SaveCont( XclExpStream& rStrm )
404 : {
405 0 : rStrm << (sal_uInt32) 0xFFFFFFFF
406 0 : << (sal_uInt32) 0x00000000
407 0 : << (sal_uInt32) 0x00000020
408 0 : << (sal_uInt16) 0xFFFF;
409 0 : lcl_WriteGUID( rStrm, aGUID );
410 0 : rStrm << (sal_uInt16) 0x04B0;
411 0 : lcl_WriteFixedString( rStrm, sUsername, 113 );
412 0 : lcl_WriteDateTime( rStrm, aDateTime );
413 0 : rStrm << (sal_uInt8) 0x0000
414 0 : << (sal_uInt16) 0x0002;
415 0 : }
416 :
417 0 : sal_uInt16 XclExpChTrInfo::GetNum() const
418 : {
419 0 : return 0x0138;
420 : }
421 :
422 0 : sal_Size XclExpChTrInfo::GetLen() const
423 : {
424 0 : return 158;
425 : }
426 :
427 0 : void XclExpChTrInfo::SaveXml( XclExpXmlStream& rRevisionHeadersStrm )
428 : {
429 0 : sax_fastparser::FSHelperPtr pHeader = rRevisionHeadersStrm.GetCurrentStream();
430 :
431 0 : OUString sRelationshipId;
432 : sax_fastparser::FSHelperPtr pRevisionLog = rRevisionHeadersStrm.CreateOutputStream(
433 : XclXmlUtils::GetStreamName( "xl/revisions/", "revisionLog", mnLogNumber ),
434 : XclXmlUtils::GetStreamName( NULL, "revisionLog", mnLogNumber ),
435 0 : rRevisionHeadersStrm.GetCurrentStream()->getOutputStream(),
436 : "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml",
437 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionLog",
438 0 : &sRelationshipId );
439 :
440 : rRevisionHeadersStrm.WriteAttributes(
441 : XML_guid, lcl_GuidToOString( aGUID ).getStr(),
442 : XML_dateTime, lcl_DateTimeToOString( aDateTime ).getStr(),
443 : XML_maxSheetId, NULL, // OOXTODO
444 : XML_userName, XclXmlUtils::ToOString( sUsername ).getStr(),
445 : FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sRelationshipId ).getStr(),
446 : XML_minRId, NULL, // OOXTODO
447 : XML_maxRId, NULL, // OOXTODO
448 0 : FSEND );
449 0 : pHeader->write( ">" );
450 :
451 0 : rRevisionHeadersStrm.PushStream( pRevisionLog );
452 0 : }
453 :
454 : //___________________________________________________________________
455 :
456 0 : XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( sal_uInt16 nCount ) :
457 : nBufSize( nCount ),
458 0 : nLastId( nCount )
459 : {
460 0 : pBuffer = new sal_uInt16[ nBufSize ];
461 0 : memset( pBuffer, 0, sizeof(sal_uInt16) * nBufSize );
462 0 : pLast = pBuffer + nBufSize - 1;
463 0 : }
464 :
465 0 : XclExpChTrTabIdBuffer::XclExpChTrTabIdBuffer( const XclExpChTrTabIdBuffer& rCopy ) :
466 : nBufSize( rCopy.nBufSize ),
467 0 : nLastId( rCopy.nLastId )
468 : {
469 0 : pBuffer = new sal_uInt16[ nBufSize ];
470 0 : memcpy( pBuffer, rCopy.pBuffer, sizeof(sal_uInt16) * nBufSize );
471 0 : pLast = pBuffer + nBufSize - 1;
472 0 : }
473 :
474 0 : XclExpChTrTabIdBuffer::~XclExpChTrTabIdBuffer()
475 : {
476 0 : delete[] pBuffer;
477 0 : }
478 :
479 0 : void XclExpChTrTabIdBuffer::InitFill( sal_uInt16 nIndex )
480 : {
481 : OSL_ENSURE( nIndex < nLastId, "XclExpChTrTabIdBuffer::Insert - out of range" );
482 :
483 0 : sal_uInt16 nFreeCount = 0;
484 0 : for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
485 : {
486 0 : if( !*pElem )
487 0 : nFreeCount++;
488 0 : if( nFreeCount > nIndex )
489 : {
490 0 : *pElem = nLastId--;
491 0 : return;
492 : }
493 : }
494 : }
495 :
496 0 : void XclExpChTrTabIdBuffer::InitFillup()
497 : {
498 0 : sal_uInt16 nFreeCount = 1;
499 0 : for( sal_uInt16* pElem = pBuffer; pElem <= pLast; pElem++ )
500 0 : if( !*pElem )
501 0 : *pElem = nFreeCount++;
502 0 : nLastId = nBufSize;
503 0 : }
504 :
505 0 : sal_uInt16 XclExpChTrTabIdBuffer::GetId( sal_uInt16 nIndex ) const
506 : {
507 : OSL_ENSURE( nIndex < nBufSize, "XclExpChTrTabIdBuffer::GetId - out of range" );
508 0 : return pBuffer[ nIndex ];
509 : }
510 :
511 0 : void XclExpChTrTabIdBuffer::Remove()
512 : {
513 : OSL_ENSURE( pBuffer <= pLast, "XclExpChTrTabIdBuffer::Remove - buffer empty" );
514 0 : sal_uInt16* pElem = pBuffer;
515 0 : while( (pElem <= pLast) && (*pElem != nLastId) )
516 0 : pElem++;
517 0 : while( pElem < pLast )
518 : {
519 0 : *pElem = *(pElem + 1);
520 0 : pElem++;
521 : }
522 0 : pLast--;
523 0 : nLastId--;
524 0 : }
525 :
526 : //___________________________________________________________________
527 :
528 0 : XclExpChTrTabId::XclExpChTrTabId( const XclExpChTrTabIdBuffer& rBuffer, bool bInRevisionHeaders )
529 0 : : nTabCount( rBuffer.GetBufferCount() )
530 0 : , mbInRevisionHeaders( bInRevisionHeaders )
531 : {
532 0 : pBuffer = new sal_uInt16[ nTabCount ];
533 0 : rBuffer.GetBufferCopy( pBuffer );
534 0 : }
535 :
536 3 : XclExpChTrTabId::~XclExpChTrTabId()
537 : {
538 1 : Clear();
539 2 : }
540 :
541 0 : void XclExpChTrTabId::Copy( const XclExpChTrTabIdBuffer& rBuffer )
542 : {
543 0 : Clear();
544 0 : nTabCount = rBuffer.GetBufferCount();
545 0 : pBuffer = new sal_uInt16[ nTabCount ];
546 0 : rBuffer.GetBufferCopy( pBuffer );
547 0 : }
548 :
549 0 : void XclExpChTrTabId::SaveCont( XclExpStream& rStrm )
550 : {
551 0 : rStrm.EnableEncryption();
552 0 : if( pBuffer )
553 0 : for( sal_uInt16* pElem = pBuffer; pElem < (pBuffer + nTabCount); pElem++ )
554 0 : rStrm << *pElem;
555 : else
556 0 : for( sal_uInt16 nIndex = 1; nIndex <= nTabCount; nIndex++ )
557 0 : rStrm << nIndex;
558 0 : }
559 :
560 0 : sal_uInt16 XclExpChTrTabId::GetNum() const
561 : {
562 0 : return 0x013D;
563 : }
564 :
565 0 : sal_Size XclExpChTrTabId::GetLen() const
566 : {
567 0 : return nTabCount << 1;
568 : }
569 :
570 1 : void XclExpChTrTabId::SaveXml( XclExpXmlStream& rRevisionLogStrm )
571 : {
572 1 : if( !mbInRevisionHeaders )
573 1 : return;
574 :
575 0 : sax_fastparser::FSHelperPtr pRevisionLog = rRevisionLogStrm.GetCurrentStream();
576 0 : rRevisionLogStrm.PopStream();
577 :
578 0 : sax_fastparser::FSHelperPtr pHeader = rRevisionLogStrm.GetCurrentStream();
579 : pHeader->startElement( XML_sheetIdMap,
580 : XML_count, OString::valueOf( sal_Int32( nTabCount ) ).getStr(),
581 0 : FSEND );
582 0 : for( int i = 0; i < nTabCount; ++i )
583 : {
584 : pHeader->singleElement( XML_sheetId,
585 0 : XML_val, OString::valueOf( sal_Int32( pBuffer[ i ] ) ).getStr(),
586 0 : FSEND );
587 : }
588 0 : pHeader->endElement( XML_sheetIdMap );
589 :
590 0 : rRevisionLogStrm.PushStream( pRevisionLog );
591 : }
592 :
593 : //___________________________________________________________________
594 :
595 : // ! does not copy additional actions
596 0 : XclExpChTrAction::XclExpChTrAction( const XclExpChTrAction& rCopy ) :
597 : ExcRecord( rCopy ),
598 : sUsername( rCopy.sUsername ),
599 : aDateTime( rCopy.aDateTime ),
600 : nIndex( 0 ),
601 : pAddAction( 0 ),
602 : bAccepted( rCopy.bAccepted ),
603 : rTabInfo( rCopy.rTabInfo ),
604 : rIdBuffer( rCopy.rIdBuffer ),
605 : nLength( rCopy.nLength ),
606 : nOpCode( rCopy.nOpCode ),
607 0 : bForceInfo( rCopy.bForceInfo )
608 : {
609 0 : }
610 :
611 0 : XclExpChTrAction::XclExpChTrAction(
612 : const ScChangeAction& rAction,
613 : const XclExpRoot& rRoot,
614 : const XclExpChTrTabIdBuffer& rTabIdBuffer,
615 : sal_uInt16 nNewOpCode ) :
616 0 : sUsername( rAction.GetUser() ),
617 : aDateTime( rAction.GetDateTime() ),
618 : nIndex( 0 ),
619 : pAddAction( NULL ),
620 0 : bAccepted( rAction.IsAccepted() ),
621 0 : rTabInfo( rRoot.GetTabInfo() ),
622 : rIdBuffer( rTabIdBuffer ),
623 : nLength( 0 ),
624 : nOpCode( nNewOpCode ),
625 0 : bForceInfo( false )
626 : {
627 0 : aDateTime.SetSec( 0 );
628 0 : aDateTime.Set100Sec( 0 );
629 0 : }
630 :
631 0 : XclExpChTrAction::~XclExpChTrAction()
632 : {
633 0 : if( pAddAction )
634 0 : delete pAddAction;
635 0 : }
636 :
637 0 : void XclExpChTrAction::SetAddAction( XclExpChTrAction* pAction )
638 : {
639 0 : if( pAddAction )
640 0 : pAddAction->SetAddAction( pAction );
641 : else
642 0 : pAddAction = pAction;
643 0 : }
644 :
645 0 : void XclExpChTrAction::AddDependentContents(
646 : const ScChangeAction& rAction,
647 : const XclExpRoot& rRoot,
648 : ScChangeTrack& rChangeTrack )
649 : {
650 0 : ScChangeActionMap aActionMap;
651 0 : ScChangeActionMap::iterator itChangeAction;
652 :
653 0 : rChangeTrack.GetDependents( (ScChangeAction*)(&rAction), aActionMap );
654 0 : for( itChangeAction = aActionMap.begin(); itChangeAction != aActionMap.end(); ++itChangeAction )
655 0 : if( itChangeAction->second->GetType() == SC_CAT_CONTENT )
656 : SetAddAction( new XclExpChTrCellContent(
657 0 : *((const ScChangeActionContent*) itChangeAction->second), rRoot, rIdBuffer ) );
658 0 : }
659 :
660 0 : void XclExpChTrAction::SetIndex( sal_uInt32& rIndex )
661 : {
662 0 : nIndex = rIndex++;
663 0 : }
664 :
665 0 : void XclExpChTrAction::SaveCont( XclExpStream& rStrm )
666 : {
667 : OSL_ENSURE( nOpCode != EXC_CHTR_OP_UNKNOWN, "XclExpChTrAction::SaveCont - unknown action" );
668 0 : rStrm << nLength
669 0 : << nIndex
670 0 : << nOpCode
671 0 : << (sal_uInt16)(bAccepted ? EXC_CHTR_ACCEPT : EXC_CHTR_NOTHING);
672 0 : SaveActionData( rStrm );
673 0 : }
674 :
675 0 : void XclExpChTrAction::PrepareSaveAction( XclExpStream& /*rStrm*/ ) const
676 : {
677 0 : }
678 :
679 0 : void XclExpChTrAction::CompleteSaveAction( XclExpStream& /*rStrm*/ ) const
680 : {
681 0 : }
682 :
683 0 : void XclExpChTrAction::Save( XclExpStream& rStrm )
684 : {
685 0 : PrepareSaveAction( rStrm );
686 0 : ExcRecord::Save( rStrm );
687 0 : if( pAddAction )
688 0 : pAddAction->Save( rStrm );
689 0 : CompleteSaveAction( rStrm );
690 0 : }
691 :
692 0 : sal_Size XclExpChTrAction::GetLen() const
693 : {
694 0 : return GetHeaderByteCount() + GetActionByteCount();
695 : }
696 :
697 : //___________________________________________________________________
698 :
699 0 : XclExpChTrData::XclExpChTrData() :
700 : pString( NULL ),
701 : mpFormulaCell( NULL ),
702 : fValue( 0.0 ),
703 : nRKValue( 0 ),
704 : nType( EXC_CHTR_TYPE_EMPTY ),
705 0 : nSize( 0 )
706 : {
707 0 : }
708 :
709 0 : XclExpChTrData::~XclExpChTrData()
710 : {
711 0 : Clear();
712 0 : }
713 :
714 0 : void XclExpChTrData::Clear()
715 : {
716 0 : DELETEZ( pString );
717 0 : mpFormulaCell = NULL;
718 0 : mxTokArr.reset();
719 0 : maRefLog.clear();
720 0 : fValue = 0.0;
721 0 : nRKValue = 0;
722 0 : nType = EXC_CHTR_TYPE_EMPTY;
723 0 : nSize = 0;
724 0 : }
725 :
726 0 : void XclExpChTrData::WriteFormula( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
727 : {
728 : OSL_ENSURE( mxTokArr && !mxTokArr->Empty(), "XclExpChTrData::Write - no formula" );
729 0 : rStrm << *mxTokArr;
730 :
731 0 : for( XclExpRefLog::const_iterator aIt = maRefLog.begin(), aEnd = maRefLog.end(); aIt != aEnd; ++aIt )
732 : {
733 0 : if( aIt->mpUrl && aIt->mpFirstTab )
734 : {
735 0 : rStrm << *aIt->mpUrl << (sal_uInt8) 0x01 << *aIt->mpFirstTab << (sal_uInt8) 0x02;
736 : }
737 : else
738 : {
739 0 : bool bSingleTab = aIt->mnFirstXclTab == aIt->mnLastXclTab;
740 0 : rStrm.SetSliceSize( bSingleTab ? 6 : 8 );
741 0 : rStrm << (sal_uInt8) 0x01 << (sal_uInt8) 0x02 << (sal_uInt8) 0x00;
742 0 : rStrm << rTabIdBuffer.GetId( aIt->mnFirstXclTab );
743 0 : if( bSingleTab )
744 0 : rStrm << (sal_uInt8) 0x02;
745 : else
746 0 : rStrm << (sal_uInt8) 0x00 << rTabIdBuffer.GetId( aIt->mnLastXclTab );
747 : }
748 : }
749 0 : rStrm.SetSliceSize( 0 );
750 0 : rStrm << (sal_uInt8) 0x00;
751 0 : }
752 :
753 0 : void XclExpChTrData::Write( XclExpStream& rStrm, const XclExpChTrTabIdBuffer& rTabIdBuffer )
754 : {
755 0 : switch( nType )
756 : {
757 : case EXC_CHTR_TYPE_RK:
758 0 : rStrm << nRKValue;
759 0 : break;
760 : case EXC_CHTR_TYPE_DOUBLE:
761 0 : rStrm << fValue;
762 0 : break;
763 : case EXC_CHTR_TYPE_STRING:
764 : OSL_ENSURE( pString, "XclExpChTrData::Write - no string" );
765 0 : rStrm << *pString;
766 0 : break;
767 : case EXC_CHTR_TYPE_FORMULA:
768 0 : WriteFormula( rStrm, rTabIdBuffer );
769 0 : break;
770 : }
771 0 : }
772 :
773 : //___________________________________________________________________
774 :
775 0 : XclExpChTrCellContent::XclExpChTrCellContent(
776 : const ScChangeActionContent& rAction,
777 : const XclExpRoot& rRoot,
778 : const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
779 : XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_CELL ),
780 : XclExpRoot( rRoot ),
781 : pOldData( 0 ),
782 : pNewData( 0 ),
783 0 : aPosition( rAction.GetBigRange().MakeRange().aStart )
784 : {
785 : sal_uInt32 nDummy32;
786 : sal_uInt16 nDummy16;
787 0 : GetCellData( rRoot, rAction.GetOldCell(), pOldData, nDummy32, nOldLength );
788 0 : GetCellData( rRoot, rAction.GetNewCell(), pNewData, nLength, nDummy16 );
789 0 : }
790 :
791 0 : XclExpChTrCellContent::~XclExpChTrCellContent()
792 : {
793 0 : if( pOldData )
794 0 : delete pOldData;
795 0 : if( pNewData )
796 0 : delete pNewData;
797 0 : }
798 :
799 0 : void XclExpChTrCellContent::MakeEmptyChTrData( XclExpChTrData*& rpData )
800 : {
801 0 : if( rpData )
802 0 : rpData->Clear();
803 : else
804 0 : rpData = new XclExpChTrData;
805 0 : }
806 :
807 0 : void XclExpChTrCellContent::GetCellData(
808 : const XclExpRoot& rRoot,
809 : const ScBaseCell* pScCell,
810 : XclExpChTrData*& rpData,
811 : sal_uInt32& rXclLength1,
812 : sal_uInt16& rXclLength2 )
813 : {
814 0 : MakeEmptyChTrData( rpData );
815 0 : rXclLength1 = 0x0000003A;
816 0 : rXclLength2 = 0x0000;
817 :
818 0 : if( !pScCell )
819 : {
820 0 : delete rpData;
821 0 : rpData = NULL;
822 0 : return;
823 : }
824 :
825 0 : switch( pScCell->GetCellType() )
826 : {
827 : case CELLTYPE_VALUE:
828 : {
829 0 : rpData->fValue = ((const ScValueCell*) pScCell)->GetValue();
830 0 : if( XclTools::GetRKFromDouble( rpData->nRKValue, rpData->fValue ) )
831 : {
832 0 : rpData->nType = EXC_CHTR_TYPE_RK;
833 0 : rpData->nSize = 4;
834 0 : rXclLength1 = 0x0000003E;
835 0 : rXclLength2 = 0x0004;
836 : }
837 : else
838 : {
839 0 : rpData->nType = EXC_CHTR_TYPE_DOUBLE;
840 0 : rpData->nSize = 8;
841 0 : rXclLength1 = 0x00000042;
842 0 : rXclLength2 = 0x0008;
843 : }
844 : }
845 0 : break;
846 : case CELLTYPE_STRING:
847 : case CELLTYPE_EDIT:
848 : {
849 0 : String sCellStr;
850 0 : if( pScCell->GetCellType() == CELLTYPE_STRING )
851 : {
852 0 : const ScStringCell* pStrCell = static_cast< const ScStringCell* >( pScCell );
853 0 : sCellStr = pStrCell->GetString();
854 : rpData->mpFormattedString = XclExpStringHelper::CreateCellString( rRoot,
855 0 : *pStrCell, NULL );
856 : }
857 : else
858 : {
859 0 : const ScEditCell* pEditCell = static_cast< const ScEditCell* >( pScCell );
860 0 : sCellStr = pEditCell->GetString();
861 0 : XclExpHyperlinkHelper aLinkHelper( rRoot, aPosition );
862 : rpData->mpFormattedString = XclExpStringHelper::CreateCellString( rRoot,
863 0 : *pEditCell, NULL, aLinkHelper );
864 : }
865 0 : rpData->pString = new XclExpString( sCellStr, EXC_STR_DEFAULT, 32766 );
866 0 : rpData->nType = EXC_CHTR_TYPE_STRING;
867 0 : rpData->nSize = 3 + rpData->pString->GetSize();
868 0 : rXclLength1 = 64 + (sCellStr.Len() << 1);
869 0 : rXclLength2 = 6 + (sal_uInt16)(sCellStr.Len() << 1);
870 : }
871 0 : break;
872 : case CELLTYPE_FORMULA:
873 : {
874 0 : const ScFormulaCell* pFmlCell = (const ScFormulaCell*) pScCell;
875 0 : rpData->mpFormulaCell = pFmlCell;
876 :
877 0 : const ScTokenArray* pTokenArray = pFmlCell->GetCode();
878 0 : if( pTokenArray )
879 : {
880 0 : XclExpRefLog& rRefLog = rpData->maRefLog;
881 0 : rpData->mxTokArr = GetFormulaCompiler().CreateFormula(
882 0 : EXC_FMLATYPE_CELL, *pTokenArray, &pFmlCell->aPos, &rRefLog );
883 0 : rpData->nType = EXC_CHTR_TYPE_FORMULA;
884 0 : sal_Size nSize = rpData->mxTokArr->GetSize() + 3;
885 :
886 0 : for( XclExpRefLog::const_iterator aIt = rRefLog.begin(), aEnd = rRefLog.end(); aIt != aEnd; ++aIt )
887 : {
888 0 : if( aIt->mpUrl && aIt->mpFirstTab )
889 0 : nSize += aIt->mpUrl->GetSize() + aIt->mpFirstTab->GetSize() + 2;
890 : else
891 0 : nSize += (aIt->mnFirstXclTab == aIt->mnLastXclTab) ? 6 : 8;
892 : }
893 0 : rpData->nSize = ::std::min< sal_Size >( nSize, 0xFFFF );
894 0 : rXclLength1 = 0x00000052;
895 0 : rXclLength2 = 0x0018;
896 : }
897 : }
898 0 : break;
899 : default:;
900 : }
901 : }
902 :
903 0 : void XclExpChTrCellContent::SaveActionData( XclExpStream& rStrm ) const
904 : {
905 0 : WriteTabId( rStrm, aPosition.Tab() );
906 0 : rStrm << (sal_uInt16)((pOldData ? (pOldData->nType << 3) : 0x0000) | (pNewData ? pNewData->nType : 0x0000))
907 0 : << (sal_uInt16) 0x0000;
908 0 : Write2DAddress( rStrm, aPosition );
909 0 : rStrm << nOldLength
910 0 : << (sal_uInt32) 0x00000000;
911 0 : if( pOldData )
912 0 : pOldData->Write( rStrm, rIdBuffer );
913 0 : if( pNewData )
914 0 : pNewData->Write( rStrm, rIdBuffer );
915 0 : }
916 :
917 0 : sal_uInt16 XclExpChTrCellContent::GetNum() const
918 : {
919 0 : return 0x013B;
920 : }
921 :
922 0 : sal_Size XclExpChTrCellContent::GetActionByteCount() const
923 : {
924 0 : sal_Size nLen = 16;
925 0 : if( pOldData )
926 0 : nLen += pOldData->nSize;
927 0 : if( pNewData )
928 0 : nLen += pNewData->nSize;
929 0 : return nLen;
930 : }
931 :
932 0 : static const char* lcl_GetType( XclExpChTrData* pData )
933 : {
934 0 : switch( pData->nType )
935 : {
936 : case EXC_CHTR_TYPE_RK:
937 : case EXC_CHTR_TYPE_DOUBLE:
938 0 : return "n";
939 : break;
940 : case EXC_CHTR_TYPE_FORMULA:
941 : {
942 0 : ScFormulaCell* pFormulaCell = const_cast< ScFormulaCell* >( pData->mpFormulaCell );
943 : const char* sType;
944 0 : OUString sValue;
945 0 : XclXmlUtils::GetFormulaTypeAndValue( *pFormulaCell, sType, sValue );
946 0 : return sType;
947 : }
948 : break;
949 : case EXC_CHTR_TYPE_STRING:
950 0 : return "inlineStr";
951 : break;
952 : default:
953 0 : break;
954 : }
955 0 : return "*unknown*";
956 : }
957 :
958 0 : static void lcl_WriteCell( XclExpXmlStream& rStrm, sal_Int32 nElement, const ScAddress& rPosition, XclExpChTrData* pData )
959 : {
960 0 : sax_fastparser::FSHelperPtr pStream = rStrm.GetCurrentStream();
961 :
962 : pStream->startElement( nElement,
963 : XML_r, XclXmlUtils::ToOString( rPosition ).getStr(),
964 : XML_s, NULL, // OOXTODO: not supported
965 : XML_t, lcl_GetType( pData ),
966 : XML_cm, NULL, // OOXTODO: not supported
967 : XML_vm, NULL, // OOXTODO: not supported
968 : XML_ph, NULL, // OOXTODO: not supported
969 0 : FSEND );
970 0 : switch( pData->nType )
971 : {
972 : case EXC_CHTR_TYPE_RK:
973 : case EXC_CHTR_TYPE_DOUBLE:
974 0 : pStream->startElement( XML_v, FSEND );
975 0 : pStream->write( pData->fValue );
976 0 : pStream->endElement( XML_v );
977 0 : break;
978 : case EXC_CHTR_TYPE_FORMULA:
979 : pStream->startElement( XML_f,
980 : // OOXTODO: other attributes? see XclExpFormulaCell::SaveXml()
981 0 : FSEND );
982 : pStream->writeEscaped( XclXmlUtils::ToOUString(
983 0 : *pData->mpFormulaCell->GetDocument(),
984 0 : pData->mpFormulaCell->aPos, pData->mpFormulaCell->GetCode() ) );
985 0 : pStream->endElement( XML_f );
986 0 : break;
987 : case EXC_CHTR_TYPE_STRING:
988 0 : pStream->startElement( XML_is, FSEND );
989 0 : if( pData->mpFormattedString )
990 0 : pData->mpFormattedString->WriteXml( rStrm );
991 : else
992 0 : pData->pString->WriteXml( rStrm );
993 0 : pStream->endElement( XML_is );
994 0 : break;
995 : default:
996 : // ignore
997 0 : break;
998 : }
999 0 : pStream->endElement( nElement );
1000 0 : }
1001 :
1002 0 : void XclExpChTrCellContent::SaveXml( XclExpXmlStream& rRevisionLogStrm )
1003 : {
1004 0 : sax_fastparser::FSHelperPtr pStream = rRevisionLogStrm.GetCurrentStream();
1005 : pStream->startElement( XML_rcc,
1006 0 : XML_rId, OString::valueOf( (sal_Int32) GetActionNumber() ).getStr(),
1007 0 : XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
1008 : XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
1009 0 : XML_sId, OString::valueOf( (sal_Int32) GetTabId( aPosition.Tab() ) ).getStr(),
1010 : XML_odxf, NULL, // OOXTODO: not supported
1011 : XML_xfDxf, NULL, // OOXTODO: not supported
1012 : XML_s, NULL, // OOXTODO: not supported
1013 : XML_dxf, NULL, // OOXTODO: not supported
1014 : XML_numFmtId, NULL, // OOXTODO: not supported
1015 : XML_quotePrefix, NULL, // OOXTODO: not supported
1016 : XML_oldQuotePrefix, NULL, // OOXTODO: not supported
1017 : XML_ph, NULL, // OOXTODO: not supported
1018 : XML_oldPh, NULL, // OOXTODO: not supported
1019 : XML_endOfListFormulaUpdate, NULL, // OOXTODO: not supported
1020 0 : FSEND );
1021 0 : if( pOldData )
1022 : {
1023 0 : lcl_WriteCell( rRevisionLogStrm, XML_oc, aPosition, pOldData );
1024 : }
1025 0 : if( pNewData )
1026 : {
1027 0 : lcl_WriteCell( rRevisionLogStrm, XML_nc, aPosition, pNewData );
1028 : }
1029 : // OOXTODO: XML_odxf, XML_ndxf, XML_extLst elements
1030 0 : pStream->endElement( XML_rcc );
1031 0 : }
1032 :
1033 : //___________________________________________________________________
1034 :
1035 0 : XclExpChTrInsert::XclExpChTrInsert(
1036 : const ScChangeAction& rAction,
1037 : const XclExpRoot& rRoot,
1038 : const XclExpChTrTabIdBuffer& rTabIdBuffer,
1039 : ScChangeTrack& rChangeTrack ) :
1040 : XclExpChTrAction( rAction, rRoot, rTabIdBuffer ),
1041 0 : aRange( rAction.GetBigRange().MakeRange() )
1042 : {
1043 0 : nLength = 0x00000030;
1044 0 : switch( rAction.GetType() )
1045 : {
1046 0 : case SC_CAT_INSERT_COLS: nOpCode = EXC_CHTR_OP_INSCOL; break;
1047 0 : case SC_CAT_INSERT_ROWS: nOpCode = EXC_CHTR_OP_INSROW; break;
1048 0 : case SC_CAT_DELETE_COLS: nOpCode = EXC_CHTR_OP_DELCOL; break;
1049 0 : case SC_CAT_DELETE_ROWS: nOpCode = EXC_CHTR_OP_DELROW; break;
1050 : default:
1051 : OSL_FAIL( "XclExpChTrInsert::XclExpChTrInsert - unknown action" );
1052 : }
1053 :
1054 0 : if( nOpCode & EXC_CHTR_OP_COLFLAG )
1055 : {
1056 0 : aRange.aStart.SetRow( 0 );
1057 0 : aRange.aEnd.SetRow( rRoot.GetXclMaxPos().Row() );
1058 : }
1059 : else
1060 : {
1061 0 : aRange.aStart.SetCol( 0 );
1062 0 : aRange.aEnd.SetCol( rRoot.GetXclMaxPos().Col() );
1063 : }
1064 :
1065 0 : if( nOpCode & EXC_CHTR_OP_DELFLAG )
1066 : {
1067 0 : SetAddAction( new XclExpChTr0x014A( *this ) );
1068 0 : AddDependentContents( rAction, rRoot, rChangeTrack );
1069 : }
1070 0 : }
1071 :
1072 0 : XclExpChTrInsert::~XclExpChTrInsert()
1073 : {
1074 0 : }
1075 :
1076 0 : void XclExpChTrInsert::SaveActionData( XclExpStream& rStrm ) const
1077 : {
1078 0 : WriteTabId( rStrm, aRange.aStart.Tab() );
1079 0 : rStrm << (sal_uInt16) 0x0000;
1080 0 : Write2DRange( rStrm, aRange );
1081 0 : rStrm << (sal_uInt32) 0x00000000;
1082 0 : }
1083 :
1084 0 : void XclExpChTrInsert::PrepareSaveAction( XclExpStream& rStrm ) const
1085 : {
1086 0 : if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) )
1087 0 : XclExpChTrEmpty( 0x0150 ).Save( rStrm );
1088 0 : }
1089 :
1090 0 : void XclExpChTrInsert::CompleteSaveAction( XclExpStream& rStrm ) const
1091 : {
1092 0 : if( (nOpCode == EXC_CHTR_OP_DELROW) || (nOpCode == EXC_CHTR_OP_DELCOL) )
1093 0 : XclExpChTrEmpty( 0x0151 ).Save( rStrm );
1094 0 : }
1095 :
1096 0 : sal_uInt16 XclExpChTrInsert::GetNum() const
1097 : {
1098 0 : return 0x0137;
1099 : }
1100 :
1101 0 : sal_Size XclExpChTrInsert::GetActionByteCount() const
1102 : {
1103 0 : return 16;
1104 : }
1105 :
1106 0 : static const char* lcl_GetAction( sal_uInt16 nOpCode )
1107 : {
1108 0 : switch( nOpCode )
1109 : {
1110 0 : case EXC_CHTR_OP_INSCOL: return "insertCol";
1111 0 : case EXC_CHTR_OP_INSROW: return "insertRow";
1112 0 : case EXC_CHTR_OP_DELCOL: return "deleteCol";
1113 0 : case EXC_CHTR_OP_DELROW: return "deleteRow";
1114 0 : default: return "*unknown*";
1115 : }
1116 : }
1117 :
1118 0 : void XclExpChTrInsert::SaveXml( XclExpXmlStream& rRevisionLogStrm )
1119 : {
1120 0 : sax_fastparser::FSHelperPtr pStream = rRevisionLogStrm.GetCurrentStream();
1121 : pStream->startElement( XML_rrc,
1122 0 : XML_rId, OString::valueOf( (sal_Int32) GetActionNumber() ).getStr(),
1123 0 : XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
1124 : XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
1125 0 : XML_sId, OString::valueOf( (sal_Int32) GetTabId( aRange.aStart.Tab() ) ).getStr(),
1126 : XML_eol, NULL, // OOXTODO: not supported?
1127 : XML_ref, XclXmlUtils::ToOString( aRange ).getStr(),
1128 : XML_action, lcl_GetAction( nOpCode ),
1129 : XML_edge, NULL, // OOXTODO: ???
1130 0 : FSEND );
1131 : // OOXTODO: does this handle XML_rfmt, XML_undo?
1132 0 : XclExpChTrAction* pAction = GetAddAction();
1133 0 : while( pAction != NULL )
1134 : {
1135 0 : pAction->SaveXml( rRevisionLogStrm );
1136 0 : pAction = pAction->GetAddAction();
1137 : }
1138 0 : pStream->endElement( XML_rrc );
1139 0 : }
1140 :
1141 : //___________________________________________________________________
1142 :
1143 0 : XclExpChTrInsertTab::XclExpChTrInsertTab(
1144 : const ScChangeAction& rAction,
1145 : const XclExpRoot& rRoot,
1146 : const XclExpChTrTabIdBuffer& rTabIdBuffer ) :
1147 : XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_INSTAB ),
1148 : XclExpRoot( rRoot ),
1149 0 : nTab( (SCTAB) rAction.GetBigRange().aStart.Tab() )
1150 : {
1151 0 : nLength = 0x0000021C;
1152 0 : bForceInfo = sal_True;
1153 0 : }
1154 :
1155 0 : XclExpChTrInsertTab::~XclExpChTrInsertTab()
1156 : {
1157 0 : }
1158 :
1159 0 : void XclExpChTrInsertTab::SaveActionData( XclExpStream& rStrm ) const
1160 : {
1161 0 : WriteTabId( rStrm, nTab );
1162 0 : rStrm << sal_uInt32( 0 );
1163 0 : lcl_WriteFixedString( rStrm, XclExpString( GetTabInfo().GetScTabName( nTab ) ), 127 );
1164 0 : lcl_WriteDateTime( rStrm, GetDateTime() );
1165 0 : rStrm.WriteZeroBytes( 133 );
1166 0 : }
1167 :
1168 0 : sal_uInt16 XclExpChTrInsertTab::GetNum() const
1169 : {
1170 0 : return 0x014D;
1171 : }
1172 :
1173 0 : sal_Size XclExpChTrInsertTab::GetActionByteCount() const
1174 : {
1175 0 : return 276;
1176 : }
1177 :
1178 0 : void XclExpChTrInsertTab::SaveXml( XclExpXmlStream& rStrm )
1179 : {
1180 0 : sax_fastparser::FSHelperPtr pStream = rStrm.GetCurrentStream();
1181 : pStream->singleElement( XML_ris,
1182 0 : XML_rId, OString::valueOf( (sal_Int32) GetActionNumber() ).getStr(),
1183 0 : XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
1184 : XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
1185 0 : XML_sheetId, OString::valueOf( (sal_Int32) GetTabId( nTab ) ).getStr(),
1186 0 : XML_name, XclXmlUtils::ToOString( GetTabInfo().GetScTabName( nTab ) ).getStr(),
1187 : XML_sheetPosition, OString::valueOf( (sal_Int32) nTab ).getStr(),
1188 0 : FSEND );
1189 0 : }
1190 :
1191 : //___________________________________________________________________
1192 :
1193 0 : XclExpChTrMoveRange::XclExpChTrMoveRange(
1194 : const ScChangeActionMove& rAction,
1195 : const XclExpRoot& rRoot,
1196 : const XclExpChTrTabIdBuffer& rTabIdBuffer,
1197 : ScChangeTrack& rChangeTrack ) :
1198 : XclExpChTrAction( rAction, rRoot, rTabIdBuffer, EXC_CHTR_OP_MOVE ),
1199 0 : aDestRange( rAction.GetBigRange().MakeRange() )
1200 : {
1201 0 : nLength = 0x00000042;
1202 0 : aSourceRange = aDestRange;
1203 : sal_Int32 nDCols, nDRows, nDTabs;
1204 0 : rAction.GetDelta( nDCols, nDRows, nDTabs );
1205 0 : aSourceRange.aStart.IncRow( (SCROW) -nDRows );
1206 0 : aSourceRange.aStart.IncCol( (SCCOL) -nDCols );
1207 0 : aSourceRange.aStart.IncTab( (SCTAB) -nDTabs );
1208 0 : aSourceRange.aEnd.IncRow( (SCROW) -nDRows );
1209 0 : aSourceRange.aEnd.IncCol( (SCCOL) -nDCols );
1210 0 : aSourceRange.aEnd.IncTab( (SCTAB) -nDTabs );
1211 0 : AddDependentContents( rAction, rRoot, rChangeTrack );
1212 0 : }
1213 :
1214 0 : XclExpChTrMoveRange::~XclExpChTrMoveRange()
1215 : {
1216 0 : }
1217 :
1218 0 : void XclExpChTrMoveRange::SaveActionData( XclExpStream& rStrm ) const
1219 : {
1220 0 : WriteTabId( rStrm, aDestRange.aStart.Tab() );
1221 0 : Write2DRange( rStrm, aSourceRange );
1222 0 : Write2DRange( rStrm, aDestRange );
1223 0 : WriteTabId( rStrm, aSourceRange.aStart.Tab() );
1224 0 : rStrm << (sal_uInt32) 0x00000000;
1225 0 : }
1226 :
1227 0 : void XclExpChTrMoveRange::PrepareSaveAction( XclExpStream& rStrm ) const
1228 : {
1229 0 : XclExpChTrEmpty( 0x014E ).Save( rStrm );
1230 0 : }
1231 :
1232 0 : void XclExpChTrMoveRange::CompleteSaveAction( XclExpStream& rStrm ) const
1233 : {
1234 0 : XclExpChTrEmpty( 0x014F ).Save( rStrm );
1235 0 : }
1236 :
1237 0 : sal_uInt16 XclExpChTrMoveRange::GetNum() const
1238 : {
1239 0 : return 0x0140;
1240 : }
1241 :
1242 0 : sal_Size XclExpChTrMoveRange::GetActionByteCount() const
1243 : {
1244 0 : return 24;
1245 : }
1246 :
1247 0 : void XclExpChTrMoveRange::SaveXml( XclExpXmlStream& rRevisionLogStrm )
1248 : {
1249 0 : sax_fastparser::FSHelperPtr pStream = rRevisionLogStrm.GetCurrentStream();
1250 :
1251 : pStream->startElement( XML_rm,
1252 0 : XML_rId, OString::valueOf( (sal_Int32) GetActionNumber() ).getStr(),
1253 0 : XML_ua, XclXmlUtils::ToPsz( GetAccepted () ), // OOXTODO? bAccepted == ua or ra; not sure.
1254 : XML_ra, NULL, // OOXTODO: RRD.fUndoAction? Or RRD.fAccepted?
1255 0 : XML_sheetId, OString::valueOf( (sal_Int32) GetTabId( aDestRange.aStart.Tab() ) ).getStr(),
1256 : XML_source, XclXmlUtils::ToOString( aSourceRange ).getStr(),
1257 : XML_destination, XclXmlUtils::ToOString( aDestRange ).getStr(),
1258 0 : XML_sourceSheetId, OString::valueOf( (sal_Int32) GetTabId( aSourceRange.aStart.Tab() ) ).getStr(),
1259 0 : FSEND );
1260 : // OOXTODO: does this handle XML_rfmt, XML_undo?
1261 0 : XclExpChTrAction* pAction = GetAddAction();
1262 0 : while( pAction != NULL )
1263 : {
1264 0 : pAction->SaveXml( rRevisionLogStrm );
1265 0 : pAction = pAction->GetAddAction();
1266 : }
1267 0 : pStream->endElement( XML_rm );
1268 0 : }
1269 :
1270 : //___________________________________________________________________
1271 :
1272 0 : XclExpChTr0x014A::XclExpChTr0x014A( const XclExpChTrInsert& rAction ) :
1273 0 : XclExpChTrInsert( rAction )
1274 : {
1275 0 : nLength = 0x00000026;
1276 0 : nOpCode = EXC_CHTR_OP_FORMAT;
1277 0 : }
1278 :
1279 0 : XclExpChTr0x014A::~XclExpChTr0x014A()
1280 : {
1281 0 : }
1282 :
1283 0 : void XclExpChTr0x014A::SaveActionData( XclExpStream& rStrm ) const
1284 : {
1285 0 : WriteTabId( rStrm, aRange.aStart.Tab() );
1286 0 : rStrm << (sal_uInt16) 0x0003
1287 0 : << (sal_uInt16) 0x0001;
1288 0 : Write2DRange( rStrm, aRange );
1289 0 : }
1290 :
1291 0 : sal_uInt16 XclExpChTr0x014A::GetNum() const
1292 : {
1293 0 : return 0x014A;
1294 : }
1295 :
1296 0 : sal_Size XclExpChTr0x014A::GetActionByteCount() const
1297 : {
1298 0 : return 14;
1299 : }
1300 :
1301 0 : void XclExpChTr0x014A::SaveXml( XclExpXmlStream& rStrm )
1302 : {
1303 0 : sax_fastparser::FSHelperPtr pStream = rStrm.GetCurrentStream();
1304 :
1305 : pStream->startElement( XML_rfmt,
1306 0 : XML_sheetId, OString::valueOf( (sal_Int32) GetTabId( aRange.aStart.Tab() ) ).getStr(),
1307 : XML_xfDxf, NULL, // OOXTODO: not supported
1308 : XML_s, NULL, // OOXTODO: style
1309 : XML_sqref, XclXmlUtils::ToOString( aRange ).getStr(),
1310 : XML_start, NULL, // OOXTODO: for string changes
1311 : XML_length, NULL, // OOXTODO: for string changes
1312 0 : FSEND );
1313 : // OOXTODO: XML_dxf, XML_extLst
1314 :
1315 0 : pStream->endElement( XML_rfmt );
1316 0 : }
1317 :
1318 : //___________________________________________________________________
1319 :
1320 0 : class ExcXmlRecord : public ExcRecord
1321 : {
1322 : public:
1323 : virtual sal_Size GetLen() const;
1324 : virtual sal_uInt16 GetNum() const;
1325 : virtual void Save( XclExpStream& rStrm );
1326 : virtual void SaveXml( XclExpXmlStream& rStrm ) = 0;
1327 : };
1328 :
1329 0 : sal_Size ExcXmlRecord::GetLen() const
1330 : {
1331 0 : return 0;
1332 : }
1333 :
1334 0 : sal_uInt16 ExcXmlRecord::GetNum() const
1335 : {
1336 0 : return 0;
1337 : }
1338 :
1339 0 : void ExcXmlRecord::Save( XclExpStream& )
1340 : {
1341 : // Do nothing; ignored for BIFF output.
1342 0 : }
1343 :
1344 0 : class StartXmlElement : public ExcXmlRecord
1345 : {
1346 : public:
1347 : enum Behavior {
1348 : CLOSE_ELEMENT = 0x1,
1349 : WRITE_NAMESPACES = 0x2,
1350 : };
1351 0 : StartXmlElement( sal_Int32 nElement, sal_Int32 eBehavior )
1352 0 : : mnElement( nElement ), meBehavior( (Behavior) eBehavior ) {}
1353 : virtual void SaveXml( XclExpXmlStream& rStrm );
1354 : private:
1355 : sal_Int32 mnElement;
1356 : Behavior meBehavior;
1357 : };
1358 :
1359 0 : void StartXmlElement::SaveXml( XclExpXmlStream& rStrm )
1360 : {
1361 0 : sax_fastparser::FSHelperPtr pStream = rStrm.GetCurrentStream();
1362 : pStream->write( "<" )
1363 0 : ->writeId( mnElement );
1364 0 : if( meBehavior & WRITE_NAMESPACES )
1365 : {
1366 : rStrm.WriteAttributes(
1367 : XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1368 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
1369 0 : FSEND );
1370 : }
1371 0 : if( meBehavior & CLOSE_ELEMENT )
1372 : {
1373 0 : pStream->write( ">" );
1374 0 : }
1375 0 : }
1376 :
1377 0 : class EndXmlElement : public ExcXmlRecord
1378 : {
1379 : sal_Int32 mnElement;
1380 : public:
1381 0 : EndXmlElement( sal_Int32 nElement ) : mnElement( nElement) {}
1382 : virtual void SaveXml( XclExpXmlStream& rStrm );
1383 : };
1384 :
1385 0 : void EndXmlElement::SaveXml( XclExpXmlStream& rStrm )
1386 : {
1387 0 : rStrm.GetCurrentStream()->endElement( mnElement );
1388 0 : }
1389 :
1390 0 : class EndHeaderElement : public EndXmlElement
1391 : {
1392 : public:
1393 0 : EndHeaderElement() : EndXmlElement( XML_header ) {}
1394 : virtual void SaveXml( XclExpXmlStream& rStrm );
1395 : };
1396 :
1397 0 : void EndHeaderElement::SaveXml( XclExpXmlStream& rStrm )
1398 : {
1399 : // Remove the `xl/revisions/revisionLogX.xml' file from the stack
1400 0 : rStrm.PopStream();
1401 :
1402 0 : EndXmlElement::SaveXml( rStrm );
1403 0 : }
1404 :
1405 0 : XclExpChangeTrack::XclExpChangeTrack( const XclExpRoot& rRoot ) :
1406 : XclExpRoot( rRoot ),
1407 : aActionStack(),
1408 : pTabIdBuffer( NULL ),
1409 : pTempDoc( NULL ),
1410 : pHeader( NULL ),
1411 0 : bValidGUID( false )
1412 : {
1413 : OSL_ENSURE( GetOldRoot().pTabId, "XclExpChangeTrack::XclExpChangeTrack - root data incomplete" );
1414 0 : if( !GetOldRoot().pTabId )
1415 : return;
1416 :
1417 0 : ScChangeTrack* pTempChangeTrack = CreateTempChangeTrack();
1418 0 : if (!pTempChangeTrack)
1419 : return;
1420 :
1421 0 : pTabIdBuffer = new XclExpChTrTabIdBuffer( GetTabInfo().GetXclTabCount() );
1422 0 : maBuffers.push_back( pTabIdBuffer );
1423 :
1424 : // calculate final table order (tab id list)
1425 : const ScChangeAction* pScAction;
1426 0 : for( pScAction = pTempChangeTrack->GetLast(); pScAction; pScAction = pScAction->GetPrev() )
1427 : {
1428 0 : if( pScAction->GetType() == SC_CAT_INSERT_TABS )
1429 : {
1430 0 : SCTAB nScTab = static_cast< SCTAB >( pScAction->GetBigRange().aStart.Tab() );
1431 0 : pTabIdBuffer->InitFill( GetTabInfo().GetXclTab( nScTab ) );
1432 : }
1433 : }
1434 0 : pTabIdBuffer->InitFillup();
1435 0 : GetOldRoot().pTabId->Copy( *pTabIdBuffer );
1436 :
1437 : // get actions in reverse order
1438 0 : pScAction = pTempChangeTrack->GetLast();
1439 0 : while( pScAction )
1440 : {
1441 0 : PushActionRecord( *pScAction );
1442 0 : const ScChangeAction* pPrevAction = pScAction->GetPrev();
1443 0 : pTempChangeTrack->Undo( pScAction->GetActionNumber(), pScAction->GetActionNumber() );
1444 0 : pScAction = pPrevAction;
1445 : }
1446 :
1447 : // build record list
1448 0 : pHeader = new XclExpChTrHeader;
1449 0 : aRecList.push_back( new StartXmlElement( XML_headers, StartXmlElement::WRITE_NAMESPACES ) );
1450 0 : aRecList.push_back( pHeader );
1451 0 : aRecList.push_back( new XclExpChTr0x0195 );
1452 0 : aRecList.push_back( new XclExpChTr0x0194( *pTempChangeTrack ) );
1453 :
1454 0 : String sLastUsername;
1455 0 : DateTime aLastDateTime( DateTime::EMPTY );
1456 0 : sal_uInt32 nIndex = 1;
1457 0 : sal_Int32 nLogNumber = 1;
1458 0 : while( !aActionStack.empty() )
1459 : {
1460 0 : XclExpChTrAction* pAction = aActionStack.top();
1461 0 : aActionStack.pop();
1462 :
1463 0 : if( (nIndex == 1) || pAction->ForceInfoRecord() ||
1464 0 : (pAction->GetUsername() != sLastUsername) ||
1465 0 : (pAction->GetDateTime() != aLastDateTime) )
1466 : {
1467 0 : if( nIndex != 1 )
1468 : {
1469 0 : aRecList.push_back( new EndXmlElement( XML_revisions ) );
1470 0 : aRecList.push_back( new EndHeaderElement() );
1471 : }
1472 :
1473 0 : lcl_GenerateGUID( aGUID, bValidGUID );
1474 0 : sLastUsername = pAction->GetUsername();
1475 0 : aLastDateTime = pAction->GetDateTime();
1476 :
1477 0 : aRecList.push_back( new StartXmlElement( XML_header, 0 ) );
1478 0 : aRecList.push_back( new XclExpChTrInfo( sLastUsername, aLastDateTime, aGUID, nLogNumber++ ) );
1479 0 : aRecList.push_back( new XclExpChTrTabId( pAction->GetTabIdBuffer(), true ) );
1480 0 : aRecList.push_back( new StartXmlElement( XML_revisions, StartXmlElement::WRITE_NAMESPACES | StartXmlElement::CLOSE_ELEMENT ) );
1481 0 : pHeader->SetGUID( aGUID );
1482 : }
1483 0 : pAction->SetIndex( nIndex );
1484 0 : aRecList.push_back( pAction );
1485 : }
1486 :
1487 0 : pHeader->SetGUID( aGUID );
1488 0 : pHeader->SetCount( nIndex - 1 );
1489 0 : if( nLogNumber > 1 )
1490 : {
1491 0 : aRecList.push_back( new EndXmlElement( XML_revisions ) );
1492 0 : aRecList.push_back( new EndHeaderElement() );
1493 : }
1494 0 : aRecList.push_back( new EndXmlElement( XML_headers ) );
1495 0 : aRecList.push_back( new ExcEof );
1496 : }
1497 :
1498 0 : XclExpChangeTrack::~XclExpChangeTrack()
1499 : {
1500 0 : std::vector<ExcRecord*>::iterator prIter;
1501 0 : for ( prIter = aRecList.begin(); prIter != aRecList.end(); ++prIter )
1502 0 : delete *prIter;
1503 :
1504 0 : std::vector<XclExpChTrTabIdBuffer*>::iterator pIter;
1505 0 : for ( pIter = maBuffers.begin(); pIter != maBuffers.end(); ++pIter )
1506 0 : delete *pIter;
1507 :
1508 0 : while( !aActionStack.empty() )
1509 : {
1510 0 : delete aActionStack.top();
1511 0 : aActionStack.pop();
1512 : }
1513 :
1514 0 : if( pTempDoc )
1515 0 : delete pTempDoc;
1516 0 : }
1517 :
1518 0 : ScChangeTrack* XclExpChangeTrack::CreateTempChangeTrack()
1519 : {
1520 : // get original change track
1521 0 : ScChangeTrack* pOrigChangeTrack = GetDoc().GetChangeTrack();
1522 : OSL_ENSURE( pOrigChangeTrack, "XclExpChangeTrack::CreateTempChangeTrack - no change track data" );
1523 0 : if( !pOrigChangeTrack )
1524 0 : return NULL;
1525 :
1526 : // create empty document
1527 0 : pTempDoc = new ScDocument;
1528 : OSL_ENSURE( pTempDoc, "XclExpChangeTrack::CreateTempChangeTrack - no temp document" );
1529 0 : if( !pTempDoc )
1530 0 : return NULL;
1531 :
1532 : // adjust table count
1533 0 : SCTAB nOrigCount = GetDoc().GetTableCount();
1534 0 : rtl::OUString sTabName;
1535 0 : for( sal_Int32 nIndex = 0; nIndex < nOrigCount; nIndex++ )
1536 : {
1537 0 : pTempDoc->CreateValidTabName( sTabName );
1538 0 : pTempDoc->InsertTab( SC_TAB_APPEND, sTabName );
1539 : }
1540 : OSL_ENSURE( nOrigCount == pTempDoc->GetTableCount(),
1541 : "XclExpChangeTrack::CreateTempChangeTrack - table count mismatch" );
1542 0 : if( nOrigCount != pTempDoc->GetTableCount() )
1543 0 : return NULL;
1544 :
1545 0 : return pOrigChangeTrack->Clone(pTempDoc);
1546 : }
1547 :
1548 0 : void XclExpChangeTrack::PushActionRecord( const ScChangeAction& rAction )
1549 : {
1550 0 : XclExpChTrAction* pXclAction = NULL;
1551 0 : ScChangeTrack* pTempChangeTrack = pTempDoc->GetChangeTrack();
1552 0 : switch( rAction.GetType() )
1553 : {
1554 : case SC_CAT_CONTENT:
1555 0 : pXclAction = new XclExpChTrCellContent( (const ScChangeActionContent&) rAction, GetRoot(), *pTabIdBuffer );
1556 0 : break;
1557 : case SC_CAT_INSERT_ROWS:
1558 : case SC_CAT_INSERT_COLS:
1559 : case SC_CAT_DELETE_ROWS:
1560 : case SC_CAT_DELETE_COLS:
1561 0 : if (pTempChangeTrack)
1562 0 : pXclAction = new XclExpChTrInsert( rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
1563 0 : break;
1564 : case SC_CAT_INSERT_TABS:
1565 : {
1566 0 : pXclAction = new XclExpChTrInsertTab( rAction, GetRoot(), *pTabIdBuffer );
1567 0 : XclExpChTrTabIdBuffer* pNewBuffer = new XclExpChTrTabIdBuffer( *pTabIdBuffer );
1568 0 : pNewBuffer->Remove();
1569 0 : maBuffers.push_back( pNewBuffer );
1570 0 : pTabIdBuffer = pNewBuffer;
1571 : }
1572 0 : break;
1573 : case SC_CAT_MOVE:
1574 0 : if (pTempChangeTrack)
1575 0 : pXclAction = new XclExpChTrMoveRange( (const ScChangeActionMove&) rAction, GetRoot(), *pTabIdBuffer, *pTempChangeTrack );
1576 0 : break;
1577 : default:;
1578 : }
1579 0 : if( pXclAction )
1580 0 : aActionStack.push( pXclAction );
1581 0 : }
1582 :
1583 0 : sal_Bool XclExpChangeTrack::WriteUserNamesStream()
1584 : {
1585 0 : sal_Bool bRet = false;
1586 0 : SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_USERNAMES );
1587 : OSL_ENSURE( xSvStrm.Is(), "XclExpChangeTrack::WriteUserNamesStream - no stream" );
1588 0 : if( xSvStrm.Is() )
1589 : {
1590 0 : XclExpStream aXclStrm( *xSvStrm, GetRoot() );
1591 0 : XclExpChTr0x0191().Save( aXclStrm );
1592 0 : XclExpChTr0x0198().Save( aXclStrm );
1593 0 : XclExpChTr0x0192().Save( aXclStrm );
1594 0 : XclExpChTr0x0197().Save( aXclStrm );
1595 0 : xSvStrm->Commit();
1596 0 : bRet = sal_True;
1597 : }
1598 0 : return bRet;
1599 : }
1600 :
1601 0 : void XclExpChangeTrack::Write()
1602 : {
1603 0 : if( aRecList.empty() )
1604 0 : return;
1605 :
1606 0 : if( WriteUserNamesStream() )
1607 : {
1608 0 : SotStorageStreamRef xSvStrm = OpenStream( EXC_STREAM_REVLOG );
1609 : OSL_ENSURE( xSvStrm.Is(), "XclExpChangeTrack::Write - no stream" );
1610 0 : if( xSvStrm.Is() )
1611 : {
1612 0 : XclExpStream aXclStrm( *xSvStrm, GetRoot(), EXC_MAXRECSIZE_BIFF8 + 8 );
1613 :
1614 0 : std::vector<ExcRecord*>::iterator pIter;
1615 0 : for ( pIter = aRecList.begin(); pIter != aRecList.end(); ++pIter )
1616 0 : (*pIter)->Save(aXclStrm);
1617 :
1618 0 : xSvStrm->Commit();
1619 0 : }
1620 : }
1621 : }
1622 :
1623 0 : static void lcl_WriteUserNamesXml( XclExpXmlStream& rWorkbookStrm )
1624 : {
1625 : sax_fastparser::FSHelperPtr pUserNames = rWorkbookStrm.CreateOutputStream(
1626 : OUString(RTL_CONSTASCII_USTRINGPARAM( "xl/revisions/userNames.xml" )),
1627 : OUString(RTL_CONSTASCII_USTRINGPARAM( "revisions/userNames.xml" )),
1628 0 : rWorkbookStrm.GetCurrentStream()->getOutputStream(),
1629 : "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml",
1630 0 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/usernames" );
1631 : pUserNames->startElement( XML_users,
1632 : XML_xmlns, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1633 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
1634 : XML_count, "0",
1635 0 : FSEND );
1636 : // OOXTODO: XML_userinfo elements for each user editing the file
1637 : // Doesn't seem to be supported by .xls output either (based on
1638 : // contents of XclExpChangeTrack::WriteUserNamesStream()).
1639 0 : pUserNames->endElement( XML_users );
1640 0 : }
1641 :
1642 0 : void XclExpChangeTrack::WriteXml( XclExpXmlStream& rWorkbookStrm )
1643 : {
1644 0 : if( aRecList.empty() )
1645 0 : return;
1646 :
1647 0 : lcl_WriteUserNamesXml( rWorkbookStrm );
1648 :
1649 : sax_fastparser::FSHelperPtr pRevisionHeaders = rWorkbookStrm.CreateOutputStream(
1650 : OUString(RTL_CONSTASCII_USTRINGPARAM( "xl/revisions/revisionHeaders.xml" )),
1651 : OUString(RTL_CONSTASCII_USTRINGPARAM( "revisions/revisionHeaders.xml" )),
1652 0 : rWorkbookStrm.GetCurrentStream()->getOutputStream(),
1653 : "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml",
1654 0 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionHeaders" );
1655 : // OOXTODO: XML_userinfo elements for each user editing the file
1656 : // Doesn't seem to be supported by .xls output either (based on
1657 : // contents of XclExpChangeTrack::WriteUserNamesStream()).
1658 0 : rWorkbookStrm.PushStream( pRevisionHeaders );
1659 :
1660 0 : std::vector<ExcRecord*>::iterator pIter;
1661 0 : for ( pIter = aRecList.begin(); pIter != aRecList.end(); ++pIter )
1662 0 : (*pIter)->SaveXml(rWorkbookStrm);
1663 :
1664 0 : rWorkbookStrm.PopStream();
1665 9 : }
1666 :
1667 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|