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