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