LibreOffice Module sw (master)  1
XMLRedlineImportHelper.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 <sal/config.h>
22 #include <sal/log.hxx>
23 
24 #include <cstddef>
25 
27 #include <unotextcursor.hxx>
28 #include <unotextrange.hxx>
29 #include <unocrsr.hxx>
30 #include <ndtxt.hxx>
31 #include <doc.hxx>
34 #include <tools/datetime.hxx>
35 #include <poolfmt.hxx>
36 #include <unoredline.hxx>
38 #include "xmlimp.hxx"
39 #include <officecfg/Office/Common.hxx>
40 #include <o3tl/any.hxx>
41 #include <unotools/configmgr.hxx>
42 #include <xmloff/xmltoken.hxx>
43 #include <vcl/svapp.hxx>
44 
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::uno;
47 using namespace ::xmloff::token;
48 
49 using ::com::sun::star::text::XTextCursor;
50 using ::com::sun::star::text::XTextRange;
51 using ::com::sun::star::text::XText;
52 using ::com::sun::star::text::XWordCursor;
53 using ::com::sun::star::lang::XUnoTunnel;
54 using ::com::sun::star::beans::XPropertySet;
55 using ::com::sun::star::beans::XPropertySetInfo;
56 // collision with tools/DateTime: use UNO DateTime as util::DateTime
57 // using util::DateTime;
58 
59 // a few helper functions
60 static SwDoc* lcl_GetDocViaTunnel( Reference<XTextCursor> const & rCursor )
61 {
62  Reference<XUnoTunnel> xTunnel( rCursor, UNO_QUERY);
63  OSL_ENSURE(xTunnel.is(), "missing XUnoTunnel for XTextCursor");
64  OTextCursorHelper *const pXCursor =
65  ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xTunnel);
66  OSL_ENSURE( pXCursor, "OTextCursorHelper missing" );
67  return pXCursor ? pXCursor->GetDoc() : nullptr;
68 }
69 
70 static SwDoc* lcl_GetDocViaTunnel( Reference<XTextRange> const & rRange )
71 {
72  Reference<XUnoTunnel> xTunnel(rRange, UNO_QUERY);
73  OSL_ENSURE(xTunnel.is(), "missing XUnoTunnel for XTextRange");
74  SwXTextRange *const pXRange =
75  ::sw::UnoTunnelGetImplementation<SwXTextRange>(xTunnel);
76  // #i115174#: this may be a SvxUnoTextRange
77  // OSL_ENSURE( pXRange, "SwXTextRange missing" );
78  return pXRange ? &pXRange->GetDoc() : nullptr;
79 }
80 
81 // XTextRangeOrNodeIndexPosition: store a position into the text
82 // *either* as an XTextRange or as an SwNodeIndex. The reason is that
83 // we must store either pointers to StartNodes (because redlines may
84 // start on start nodes) or to a text position, and there appears to
85 // be no existing type that could do both. Things are complicated by
86 // the matter that (e.g in section import) we delete a few characters,
87 // which may cause bookmarks (as used by XTextRange) to be deleted.
88 
90 {
91  Reference<XTextRange> xRange;
92  std::unique_ptr<SwNodeIndex> pIndex; // pIndex will point to the *previous* node
93 
94 public:
96 
97  void Set( Reference<XTextRange> const & rRange );
98  void Set( SwNodeIndex const & rIndex );
99  void SetAsNodeIndex( Reference<XTextRange> const & rRange );
100 
101  void CopyPositionInto(SwPosition& rPos, SwDoc & rDoc);
102  SwDoc* GetDoc();
103 
104  bool IsValid();
105 };
106 
108 {
109 }
110 
111 void XTextRangeOrNodeIndexPosition::Set( Reference<XTextRange> const & rRange )
112 {
113  xRange = rRange->getStart(); // set bookmark
114  pIndex.reset();
115 }
116 
118 {
119  pIndex.reset( new SwNodeIndex(rIndex) );
120  (*pIndex)-- ; // previous node!!!
121  xRange = nullptr;
122 }
123 
125  Reference<XTextRange> const & rRange )
126 {
127  // XTextRange -> XTunnel -> SwXTextRange
128  SwDoc* pDoc = lcl_GetDocViaTunnel(rRange);
129 
130  if (!pDoc)
131  {
132  SAL_WARN("sw", "no SwDoc");
133  return;
134  }
135 
136  // SwXTextRange -> PaM
137  SwUnoInternalPaM aPaM(*pDoc);
138  bool bSuccess = ::sw::XTextRangeToSwPaM(aPaM, rRange);
139  OSL_ENSURE(bSuccess, "illegal range");
140 
141  // PaM -> Index
142  Set(aPaM.GetPoint()->nNode);
143 }
144 
145 void
147 {
148  OSL_ENSURE(IsValid(), "Can't get Position");
149 
150  // create PAM from start cursor (if no node index is present)
151  if (nullptr == pIndex)
152  {
153  SwUnoInternalPaM aUnoPaM(rDoc);
154  bool bSuccess = ::sw::XTextRangeToSwPaM(aUnoPaM, xRange);
155  OSL_ENSURE(bSuccess, "illegal range");
156 
157  rPos = *aUnoPaM.GetPoint();
158  }
159  else
160  {
161  rPos.nNode = *pIndex;
162  rPos.nNode++; // pIndex points to previous index !!!
163  rPos.nContent.Assign( rPos.nNode.GetNode().GetContentNode(), 0 );
164  }
165 }
166 
168 {
169  OSL_ENSURE(IsValid(), "Can't get Doc");
170 
171  return (nullptr != pIndex) ? pIndex->GetNodes().GetDoc() : lcl_GetDocViaTunnel(xRange);
172 }
173 
175 {
176  return ( xRange.is() || (pIndex != nullptr) );
177 }
178 
179 // RedlineInfo: temporary storage for redline data
181 {
182 public:
183  RedlineInfo();
184  ~RedlineInfo();
185 
186  // redline type (insert, delete, ...)
188 
189  // info fields:
190  OUString sAuthor; // change author string
191  OUString sComment; // change comment string
192  util::DateTime aDateTime; // change DateTime
193  bool bMergeLastParagraph; // the SwRangeRedline::IsDelLastPara flag
194 
195  // each position can may be either empty, an XTextRange, or an SwNodeIndex
196 
197  // start pos of anchor (may be empty)
199 
200  // end pos of anchor (may be empty)
202 
203  // index of content node (maybe NULL)
205 
206  // next redline info (for hierarchical redlines)
208 
209  // store whether we expect an adjustment for this redline
211 };
212 
215  sAuthor(),
216  sComment(),
217  aDateTime(),
218  bMergeLastParagraph( false ),
219  aAnchorStart(),
220  aAnchorEnd(),
221  pContentIndex(nullptr),
222  pNextRedline(nullptr),
223  bNeedsAdjustment( false )
224 {
225 }
226 
228 {
229  delete pContentIndex;
230  delete pNextRedline;
231 }
232 
233 static const char g_sShowChanges[] = "ShowChanges";
234 static const char g_sRecordChanges[] = "RecordChanges";
235 static const char g_sRedlineProtectionKey[] = "RedlineProtectionKey";
236 
238  SvXMLImport & rImport,
239  bool bNoRedlinesPlease,
240  const Reference<XPropertySet> & rModel,
241  const Reference<XPropertySet> & rImportInfo )
242  : m_rImport(rImport)
243  ,
244  m_sInsertion( GetXMLToken( XML_INSERTION )),
245  m_sDeletion( GetXMLToken( XML_DELETION )),
246  m_sFormatChange( GetXMLToken( XML_FORMAT_CHANGE )),
247  m_aRedlineMap(),
248  m_bIgnoreRedlines(bNoRedlinesPlease),
249  m_xModelPropertySet(rModel),
250  m_xImportInfoPropertySet(rImportInfo)
251 {
252  // check to see if redline mode is handled outside of component
253  bool bHandleShowChanges = true;
254  bool bHandleRecordChanges = true;
255  bool bHandleProtectionKey = true;
256  if ( m_xImportInfoPropertySet.is() )
257  {
258  Reference<XPropertySetInfo> xInfo =
259  m_xImportInfoPropertySet->getPropertySetInfo();
260 
261  bHandleShowChanges = ! xInfo->hasPropertyByName( g_sShowChanges );
262  bHandleRecordChanges = ! xInfo->hasPropertyByName( g_sRecordChanges );
263  bHandleProtectionKey = ! xInfo->hasPropertyByName( g_sRedlineProtectionKey );
264  }
265 
266  // get redline mode
267  m_bShowChanges = *o3tl::doAccess<bool>(
268  ( bHandleShowChanges ? m_xModelPropertySet : m_xImportInfoPropertySet )
270  m_bRecordChanges = *o3tl::doAccess<bool>(
271  ( bHandleRecordChanges ? m_xModelPropertySet : m_xImportInfoPropertySet )
273  {
274  Any aAny = (bHandleProtectionKey ? m_xModelPropertySet
277  aAny >>= m_aProtectionKey;
278  }
279 
280  // set redline mode to "don't record changes"
281  if( bHandleRecordChanges )
282  {
283  m_xModelPropertySet->setPropertyValue( g_sRecordChanges, makeAny(false) );
284  }
285 }
286 
288 {
289  // delete all left over (and obviously incomplete) RedlineInfos (and map)
290  for( const auto& rEntry : m_aRedlineMap )
291  {
292  RedlineInfo* pInfo = rEntry.second;
293 
294  // left-over redlines. Insert them if possible (but assert),
295  // and delete the incomplete ones. Finally, delete it.
296  if( IsReady(pInfo) )
297  {
298  OSL_FAIL("forgotten RedlineInfo; now inserted");
299  InsertIntoDocument( pInfo );
300  }
301  else
302  {
303  // try if only the adjustment was missing
304  pInfo->bNeedsAdjustment = false;
305  if( IsReady(pInfo) )
306  {
307  OSL_FAIL("RedlineInfo without adjustment; now inserted");
308  InsertIntoDocument( pInfo );
309  }
310  else
311  {
312  // this situation occurs if redlines aren't closed
313  // (i.e. end without start, or start without
314  // end). This may well be a problem in the file,
315  // rather than the code.
316  OSL_FAIL("incomplete redline (maybe file was corrupt); "
317  "now deleted");
318  }
319  }
320  delete pInfo;
321  }
322  m_aRedlineMap.clear();
323 
324  // set redline mode, either to info property set, or directly to
325  // the document
326  bool bHandleShowChanges = true;
327  bool bHandleRecordChanges = true;
328  bool bHandleProtectionKey = true;
329  if ( m_xImportInfoPropertySet.is() )
330  {
331  Reference<XPropertySetInfo> xInfo =
332  m_xImportInfoPropertySet->getPropertySetInfo();
333 
334  bHandleShowChanges = ! xInfo->hasPropertyByName( g_sShowChanges );
335  bHandleRecordChanges = ! xInfo->hasPropertyByName( g_sRecordChanges );
336  bHandleProtectionKey = ! xInfo->hasPropertyByName( g_sRedlineProtectionKey );
337  }
338 
339  // set redline mode & key
340  try
341  {
342  Any aAny;
343 
344  aAny <<= m_bShowChanges;
345  if ( bHandleShowChanges )
346  {
347  aAny <<= true;
348  m_xModelPropertySet->setPropertyValue( g_sShowChanges, aAny );
349  // TODO maybe we need some property for the view-setting?
351  assert(pDoc);
353  }
354  else
355  m_xImportInfoPropertySet->setPropertyValue( g_sShowChanges, aAny );
356 
357  aAny <<= m_bRecordChanges;
358  if ( bHandleRecordChanges )
359  m_xModelPropertySet->setPropertyValue( g_sRecordChanges, aAny );
360  else
361  m_xImportInfoPropertySet->setPropertyValue( g_sRecordChanges, aAny );
362 
363  aAny <<= m_aProtectionKey;
364  if ( bHandleProtectionKey )
365  m_xModelPropertySet->setPropertyValue( g_sRedlineProtectionKey, aAny );
366  else
367  m_xImportInfoPropertySet->setPropertyValue( g_sRedlineProtectionKey, aAny);
368  }
369  catch (const uno::RuntimeException &) // fdo#65882
370  {
371  SAL_WARN( "sw", "potentially benign ordering issue during shutdown" );
372  }
373 }
374 
376  const OUString& rType,
377  const OUString& rId,
378  const OUString& rAuthor,
379  const OUString& rComment,
380  const util::DateTime& rDateTime,
381  bool bMergeLastPara)
382 {
383  // we need to do the following:
384  // 1) parse type string
385  // 2) create RedlineInfo and fill it with data
386  // 3) check for existing redline with same ID
387  // 3a) insert redline into map
388  // 3b) attach to existing redline
389 
390  // ad 1)
392  if (rType == m_sInsertion)
393  {
394  eType = RedlineType::Insert;
395  }
396  else if (rType == m_sDeletion)
397  {
398  eType = RedlineType::Delete;
399  }
400  else if (rType == m_sFormatChange)
401  {
402  eType = RedlineType::Format;
403  }
404  else
405  {
406  // no proper type found: early out!
407  return;
408  }
409 
410  // ad 2) create a new RedlineInfo
411  RedlineInfo* pInfo = new RedlineInfo();
412 
413  // fill entries
414  pInfo->eType = eType;
415  pInfo->sAuthor = rAuthor;
416  pInfo->sComment = rComment;
417  pInfo->aDateTime = rDateTime;
418  pInfo->bMergeLastParagraph = bMergeLastPara;
419 
420  // ad 3)
421  auto itPair = m_aRedlineMap.emplace(rId, pInfo);
422  if (!itPair.second)
423  {
424  // 3b) we already have a redline with this name: hierarchical redlines
425  // insert pInfo as last element in the chain.
426  // (hierarchy sanity checking happens on inserting into the document)
427 
428  // find last element
429  RedlineInfo* pInfoChain;
430  for( pInfoChain = itPair.first->second;
431  nullptr != pInfoChain->pNextRedline;
432  pInfoChain = pInfoChain->pNextRedline) ; // empty loop
433 
434  // insert as last element
435  pInfoChain->pNextRedline = pInfo;
436  }
437 }
438 
440  Reference<XTextCursor> const & xOldCursor,
441  const OUString& rId)
442 {
443  Reference<XTextCursor> xReturn;
444 
445  // this method will modify the document directly -> lock SolarMutex
446  SolarMutexGuard aGuard;
447 
448  // get RedlineInfo
449  RedlineMapType::iterator aFind = m_aRedlineMap.find(rId);
450  if (m_aRedlineMap.end() != aFind)
451  {
452  // get document from old cursor (via tunnel)
453  SwDoc* pDoc = lcl_GetDocViaTunnel(xOldCursor);
454 
455  if (!pDoc)
456  {
457  SAL_WARN("sw", "no SwDoc => cannot create section.");
458  return nullptr;
459  }
460 
461  // create text section for redline
463  (RES_POOLCOLL_STANDARD, false );
464  SwStartNode* pRedlineNode = pDoc->GetNodes().MakeTextSection(
465  pDoc->GetNodes().GetEndOfRedlines(),
467  pColl);
468 
469  // remember node-index in RedlineInfo
470  SwNodeIndex aIndex(*pRedlineNode);
471  aFind->second->pContentIndex = new SwNodeIndex(aIndex);
472 
473  // create XText for document
474  rtl::Reference<SwXRedlineText> pXText = new SwXRedlineText(pDoc, aIndex);
475 
476  // create (UNO-) cursor
477  SwPosition aPos(*pRedlineNode);
478  SwXTextCursor *const pXCursor =
479  new SwXTextCursor(*pDoc, pXText.get(), CursorType::Redline, aPos);
480  pXCursor->GetCursor().Move(fnMoveForward, GoInNode);
481  // cast to avoid ambiguity
482  xReturn = static_cast<text::XWordCursor*>(pXCursor);
483  }
484  // else: unknown redline -> Ignore
485 
486  return xReturn;
487 }
488 
490  const OUString& rId,
491  bool bStart,
492  Reference<XTextRange> const & rRange,
493  bool bIsOutsideOfParagraph)
494 {
495  RedlineMapType::iterator aFind = m_aRedlineMap.find(rId);
496  if (m_aRedlineMap.end() != aFind)
497  {
498  // RedlineInfo found; now set Cursor
499  RedlineInfo* pInfo = aFind->second;
500  if (bIsOutsideOfParagraph)
501  {
502  // outside of paragraph: remember SwNodeIndex
503  if (bStart)
504  {
505  pInfo->aAnchorStart.SetAsNodeIndex(rRange);
506  }
507  else
508  {
509  pInfo->aAnchorEnd.SetAsNodeIndex(rRange);
510  }
511 
512  // also remember that we expect an adjustment for this redline
513  pInfo->bNeedsAdjustment = true;
514  }
515  else
516  {
517  // inside of a paragraph: use regular XTextRanges (bookmarks)
518  if (bStart)
519  pInfo->aAnchorStart.Set(rRange);
520  else
521  pInfo->aAnchorEnd.Set(rRange);
522  }
523 
524  // if this Cursor was the last missing info, we insert the
525  // node into the document
526  // then we can remove the entry from the map and destroy the object
527  if (IsReady(pInfo))
528  {
529  InsertIntoDocument(pInfo);
530  m_aRedlineMap.erase(rId);
531  delete pInfo;
532  }
533  }
534  // else: unknown Id -> ignore
535 }
536 
538  const OUString& rId)
539 {
540  // this method will modify the document directly -> lock SolarMutex
541  SolarMutexGuard aGuard;
542 
543  // start + end nodes are treated the same. For either it's
544  // necessary that the target node already exists.
545 
546  RedlineMapType::iterator aFind = m_aRedlineMap.find(rId);
547  if (m_aRedlineMap.end() != aFind)
548  {
549  // RedlineInfo found; now set Cursor
550  RedlineInfo* pInfo = aFind->second;
551 
552  pInfo->bNeedsAdjustment = false;
553 
554  // if now ready, insert into document
555  if( IsReady(pInfo) )
556  {
557  InsertIntoDocument(pInfo);
558  m_aRedlineMap.erase(rId);
559  delete pInfo;
560  }
561  }
562  // else: can't find redline -> ignore
563 }
564 
566 {
567  // we can insert a redline if we have start & end, and we don't
568  // expect adjustments for either of these
569  return ( pRedline->aAnchorEnd.IsValid() &&
570  pRedline->aAnchorStart.IsValid() &&
571  !pRedline->bNeedsAdjustment );
572 }
573 
575 {
576  OSL_ENSURE(nullptr != pRedlineInfo, "need redline info");
577  OSL_ENSURE(IsReady(pRedlineInfo), "redline info not complete yet!");
578 
579  // this method will modify the document directly -> lock SolarMutex
580  SolarMutexGuard aGuard;
581 
582  // Insert the Redline as described by pRedlineInfo into the
583  // document. If we are in insert mode, don't insert any redlines
584  // (and delete 'deleted' inline redlines)
585 
586  // get the document (from one of the positions)
587  SwDoc* pDoc = pRedlineInfo->aAnchorStart.GetDoc();
588 
589  if (!pDoc)
590  {
591  SAL_WARN("sw", "no SwDoc => cannot insert redline.");
592  return;
593  }
594 
595  // now create the PaM for the redline
596  SwPaM aPaM(pDoc->GetNodes().GetEndOfContent());
597  pRedlineInfo->aAnchorStart.CopyPositionInto(*aPaM.GetPoint(), *pDoc);
598  aPaM.SetMark();
599  pRedlineInfo->aAnchorEnd.CopyPositionInto(*aPaM.GetPoint(), *pDoc);
600 
601  // collapse PaM if (start == end)
602  if (*aPaM.GetPoint() == *aPaM.GetMark())
603  {
604  aPaM.DeleteMark();
605  }
606 
607  // cover three cases:
608  // 1) empty redlines (no range, no content)
609  // 2) check for:
610  // a) bIgnoreRedline (e.g. insert mode)
611  // b) illegal PaM range (CheckNodesRange())
612  // c) redline with empty content section (quite useless)
613  // 3) normal case: insert redline
614  SwTextNode const* pTempNode(nullptr);
615  if( !aPaM.HasMark() && (pRedlineInfo->pContentIndex == nullptr) )
616  {
617  // these redlines have no function, and will thus be ignored (just as
618  // in sw3io), so no action here
619  }
620  else if ( m_bIgnoreRedlines ||
621  !CheckNodesRange( aPaM.GetPoint()->nNode,
622  aPaM.GetMark()->nNode,
623  true )
624  || (pRedlineInfo->pContentIndex
625  && (pRedlineInfo->pContentIndex->GetIndex() + 2
626  == pRedlineInfo->pContentIndex->GetNode().EndOfSectionIndex())
627  && (pTempNode = pDoc->GetNodes()[pRedlineInfo->pContentIndex->GetIndex() + 1]->GetTextNode()) != nullptr
628  && pTempNode->GetText().isEmpty()
629  && !pTempNode->GetpSwpHints()
630  && !pTempNode->GetAnchoredFlys()))
631  {
632  // ignore redline (e.g. file loaded in insert mode):
633  // delete 'deleted' redlines and forget about the whole thing
634  if (RedlineType::Delete == pRedlineInfo->eType)
635  {
637  // And what about the "deleted nodes"?
638  // They have to be deleted as well (#i80689)!
639  if( m_bIgnoreRedlines && pRedlineInfo->pContentIndex != nullptr )
640  {
641  SwNodeIndex aIdx( *pRedlineInfo->pContentIndex );
642  const SwNode* pEnd = aIdx.GetNode().EndOfSectionNode();
643  if( pEnd )
644  {
645  SwNodeIndex aEnd( *pEnd, 1 );
646  SwPaM aDel( aIdx, aEnd );
648  }
649  }
650  }
651  }
652  else
653  {
654  // regular file loading: insert redline
655 
656  // create redline (using pRedlineData which gets copied in SwRangeRedline())
657  SwRedlineData* pRedlineData = ConvertRedline(pRedlineInfo, pDoc);
658  SwRangeRedline* pRedline =
659  new SwRangeRedline( pRedlineData, *aPaM.GetPoint(),
660  !pRedlineInfo->bMergeLastParagraph );
661 
662  // set mark
663  if( aPaM.HasMark() )
664  {
665  pRedline->SetMark();
666  *(pRedline->GetMark()) = *aPaM.GetMark();
667  }
668 
669  // set content node (if necessary)
670  if (nullptr != pRedlineInfo->pContentIndex)
671  {
672  sal_uLong nPoint = aPaM.GetPoint()->nNode.GetIndex();
673  if( nPoint < pRedlineInfo->pContentIndex->GetIndex() ||
674  nPoint > pRedlineInfo->pContentIndex->GetNode().EndOfSectionIndex() )
675  pRedline->SetContentIdx(pRedlineInfo->pContentIndex);
676 #if OSL_DEBUG_LEVEL > 1
677  else
678  OSL_FAIL( "Recursive change tracking" );
679 #endif
680  }
681 
682  // set redline mode (without doing the associated book-keeping)
684  pDoc->getIDocumentRedlineAccess().AppendRedline(pRedline, false);
686  }
687 }
688 
690  RedlineInfo* pRedlineInfo,
691  SwDoc* pDoc)
692 {
693  // convert info:
694  // 1) Author String -> Author ID (default to zero)
695  std::size_t nAuthorId = (nullptr == pDoc) ? 0 :
696  pDoc->getIDocumentRedlineAccess().InsertRedlineAuthor( pRedlineInfo->sAuthor );
697 
698  // 2) util::DateTime -> DateTime
699  DateTime aDT( DateTime::EMPTY );
700  aDT.SetYear( pRedlineInfo->aDateTime.Year );
701  aDT.SetMonth( pRedlineInfo->aDateTime.Month );
702  aDT.SetDay( pRedlineInfo->aDateTime.Day );
703  aDT.SetHour( pRedlineInfo->aDateTime.Hours );
704  aDT.SetMin( pRedlineInfo->aDateTime.Minutes );
705  aDT.SetSec( pRedlineInfo->aDateTime.Seconds );
706  aDT.SetNanoSec( pRedlineInfo->aDateTime.NanoSeconds );
707 
708  // 3) recursively convert next redline
709  // ( check presence and sanity of hierarchical redline info )
710  SwRedlineData* pNext = nullptr;
711  if ( (nullptr != pRedlineInfo->pNextRedline) &&
712  (RedlineType::Delete == pRedlineInfo->eType) &&
713  (RedlineType::Insert == pRedlineInfo->pNextRedline->eType) )
714  {
715  pNext = ConvertRedline(pRedlineInfo->pNextRedline, pDoc);
716  }
717 
718  // create redline data
719  SwRedlineData* pData = new SwRedlineData(pRedlineInfo->eType,
720  nAuthorId, aDT,
721  pRedlineInfo->sComment,
722  pNext); // next data (if available)
723 
724  return pData;
725 }
726 
728 {
729  m_bShowChanges = bShow;
730 }
731 
733 {
734  m_bRecordChanges = bRecord;
735 }
736 
738  const Sequence<sal_Int8> & rKey )
739 {
740  m_aProtectionKey = rKey;
741 }
742 
743 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:682
Starts a section of nodes in the document model.
Definition: node.hxx:303
void SetAsNodeIndex(Reference< XTextRange > const &rRange)
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
Marks a position in the document model.
Definition: pam.hxx:35
void SetContentIdx(const SwNodeIndex *)
Definition: docredln.cxx:1665
void Set(Reference< XTextRange > const &rRange)
const OUString & GetText() const
Definition: ndtxt.hxx:211
void SetSec(sal_uInt16 nNewSec)
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:219
virtual AppendResult AppendRedline(SwRangeRedline *pNewRedl, bool bCallDelete)=0
Append a new redline.
virtual void SetRedlineFlags_intern(RedlineFlags eMode)=0
Set a new redline mode.
SwNodeIndex nNode
Definition: pam.hxx:37
css::uno::Sequence< sal_Int8 > m_aProtectionKey
static bool IsReady(RedlineInfo *pRedline)
sal_uIntPtr sal_uLong
const SwPosition * GetMark() const
Definition: pam.hxx:209
XMLRedlineImportHelper(SvXMLImport &rImport, bool bIgnoreRedlines, const css::uno::Reference< css::beans::XPropertySet > &rModel, const css::uno::Reference< css::beans::XPropertySet > &rImportInfoSet)
XML_DELETION
Definition: doc.hxx:185
RedlineInfo * pNextRedline
static const char g_sRedlineProtectionKey[]
virtual void DeleteRange(SwPaM &)=0
Delete a range SwFlyFrameFormat.
::sw::DocumentRedlineManager const & GetDocumentRedlineManager() const
Definition: doc.cxx:377
SwNode & GetNode() const
Definition: ndindex.hxx:118
void SetCursor(const OUString &rId, bool bStart, css::uno::Reference< css::text::XTextRange > const &rRange, bool bIsOusideOfParagraph)
std::unique_ptr< SwNodeIndex > pIndex
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:347
void SetRecordChanges(bool bRecordChanges)
void SetHour(sal_uInt16 nNewHour)
const SwDoc & GetDoc() const
Definition: unoobj2.cxx:789
SwIndex nContent
Definition: pam.hxx:38
void SetProtectionKey(const css::uno::Sequence< sal_Int8 > &rKey)
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:458
void SetShowChanges(bool bShowChanges)
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
static const char g_sShowChanges[]
std::vector< SwFrameFormat * > const * GetAnchoredFlys() const
Definition: node.hxx:288
void SetYear(sal_Int16 nNewYear)
bool CheckNodesRange(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, bool bChkSection)
Definition: pam.cxx:236
RedlineFlags on.
void CopyPositionInto(SwPosition &rPos, SwDoc &rDoc)
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange)
Definition: unoobj2.cxx:1008
css::uno::Reference< css::text::XTextCursor > CreateRedlineTextSection(css::uno::Reference< css::text::XTextCursor > const &xOldCursor, const OUString &rId)
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:164
SwStartNode * MakeTextSection(const SwNodeIndex &rWhere, SwStartNodeType eSttNdTyp, SwTextFormatColl *pColl)
Definition: nodes.cxx:1900
XML_FORMAT_CHANGE
XTextRangeOrNodeIndexPosition aAnchorEnd
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
static SwDoc * lcl_GetDocViaTunnel(Reference< XTextCursor > const &rCursor)
bool Move(SwMoveFnCollection const &fnMove=fnMoveForward, SwGoInDoc fnGo=GoInContent)
Movement of cursor.
Definition: pam.cxx:481
css::uno::Reference< css::beans::XPropertySet > m_xImportInfoPropertySet
bool GoInNode(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:892
void SetDay(sal_uInt16 nNewDay)
SwXRedlineText provides an XText which may be used to write directly into a redline node...
Definition: unoredline.hxx:34
const SwPosition * GetPoint() const
Definition: pam.hxx:207
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
SwContentNode * GetContentNode()
Definition: node.hxx:615
void SetHideRedlines(bool const bHideRedlines)
Marks a node in the document model.
Definition: ndindex.hxx:31
virtual std::size_t InsertRedlineAuthor(const OUString &rAuthor)=0
DocumentType const eType
void AdjustStartNodeCursor(const OUString &rId)
Adjust the start (end) position for a redline that begins in a start node.
sal_uLong EndOfSectionIndex() const
Definition: node.hxx:677
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
SwUnoCursor & GetCursor()
Definition: unoobj.cxx:686
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
void Add(const OUString &rType, const OUString &rId, const OUString &rAuthor, const OUString &rComment, const css::util::DateTime &rDateTime, bool bMergeLastParagraph)
SwNodes & GetNodes()
Definition: doc.hxx:402
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
void SetNanoSec(sal_uInt32 nNewNanoSec)
void SetMin(sal_uInt16 nNewMin)
css::uno::Reference< css::beans::XPropertySet > m_xModelPropertySet
SwRedlineData * ConvertRedline(RedlineInfo *pRedline, SwDoc *pDoc)
XTextRangeOrNodeIndexPosition aAnchorStart
#define SAL_WARN(area, stream)
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:455
util::DateTime aDateTime
SwNode & GetEndOfRedlines() const
Section for all Redlines.
Definition: ndarr.hxx:159
SwDoc * GetDocFromXMLImport(SvXMLImport const &)
Definition: xmlimp.cxx:1711
SwNodeIndex * pContentIndex
void InsertIntoDocument(RedlineInfo *pRedline)
XML_INSERTION
void SetMonth(sal_uInt16 nNewMonth)
static const char g_sRecordChanges[]
no RedlineFlags
Base class of the Writer document model elements.
Definition: node.hxx:79
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)