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