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