LibreOffice Module sw (master)  1
writerhelper.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 <sal/config.h>
21 #include <sal/log.hxx>
22 
23 #include <com/sun/star/util/CloseVetoException.hpp>
24 #include <com/sun/star/util/XCloseable.hpp>
25 
26 #include <doc.hxx>
27 #include "writerhelper.hxx"
28 #include <msfilter.hxx>
29 #include <com/sun/star/container/XChild.hpp>
30 
31 #include <algorithm>
32 #include <svl/itemiter.hxx>
33 #include <svx/svdobj.hxx>
34 #include <svx/svdoole2.hxx>
35 #include <svx/fmglob.hxx>
37 #include <editeng/tstpitem.hxx>
38 #include <ndtxt.hxx>
39 #include <ndnotxt.hxx>
40 #include <fmtcntnt.hxx>
41 #include <swtable.hxx>
42 #include <frmfmt.hxx>
43 #include <flypos.hxx>
44 #include <fmtanchr.hxx>
45 #include <ndgrf.hxx>
46 #include <fmtfsize.hxx>
47 #include <SwStyleNameMapper.hxx>
48 #include <docary.hxx>
49 #include <charfmt.hxx>
50 #include <fchrfmt.hxx>
51 #include <unotools/streamwrap.hxx>
52 #include <svtools/embedhlp.hxx>
53 #include <numrule.hxx>
54 #include <vcl/svapp.hxx>
58 #include <IDocumentMarkAccess.hxx>
59 #include <IMark.hxx>
60 
61 using namespace com::sun::star;
62 
63 namespace
64 {
65  // #i98791# - adjust sorting
66  // Utility to sort SwTextFormatColl's by their assigned outline style list level
67  class outlinecmp
68  {
69  public:
70  bool operator()(const SwTextFormatColl *pA, const SwTextFormatColl *pB) const
71  {
72  // #i98791#
73  bool bResult( false );
74  const bool bIsAAssignedToOutlineStyle( pA->IsAssignedToListLevelOfOutlineStyle() );
75  const bool bIsBAssignedToOutlineStyle( pB->IsAssignedToListLevelOfOutlineStyle() );
76  if ( bIsAAssignedToOutlineStyle != bIsBAssignedToOutlineStyle )
77  {
78  bResult = bIsBAssignedToOutlineStyle;
79  }
80  else if ( !bIsAAssignedToOutlineStyle )
81  {
82  // pA and pB are equal regarding the sorting criteria.
83  // Thus return value does not matter.
84  bResult = false;
85  }
86  else
87  {
89  }
90 
91  return bResult;
92  }
93  };
94 
95  bool IsValidSlotWhich(sal_uInt16 nSlotId, sal_uInt16 nWhichId)
96  {
97  return (nSlotId != 0 && nWhichId != 0 && nSlotId != nWhichId);
98  }
99 
100  /*
101  Utility to convert a SwPosFlyFrames into a simple vector of ww8::Frames
102 
103  The crucial thing is that a ww8::Frame always has an anchor which
104  points to some content in the document. This is a requirement of exporting
105  to Word
106  */
107  ww8::Frames SwPosFlyFramesToFrames(const SwPosFlyFrames &rFlys)
108  {
109  ww8::Frames aRet;
110 
111  for(const auto& rpFly : rFlys)
112  {
113  const SwFrameFormat &rEntry = rpFly->GetFormat();
114 
115  if (const SwPosition* pAnchor = rEntry.GetAnchor().GetContentAnchor())
116  {
117  // the anchor position will be invalidated by SetRedlineFlags
118  // so set a dummy position and fix it in UpdateFramePositions
119  SwPosition const dummy(SwNodeIndex(
120  const_cast<SwNodes&>(pAnchor->nNode.GetNodes())));
121  aRet.emplace_back(rEntry, dummy);
122  }
123  else
124  {
125  SwPosition aPos(rpFly->GetNdIndex());
126 
127  if (SwTextNode* pTextNd = aPos.nNode.GetNode().GetTextNode())
128  {
129  aPos.nContent.Assign(pTextNd, 0);
130  }
131 
132  aRet.emplace_back(rEntry, aPos);
133  }
134  }
135  return aRet;
136  }
137 
138  //Utility to test if a frame is anchored at a given node index
139  class anchoredto
140  {
141  private:
142  sal_uLong const mnNode;
143  public:
144  explicit anchoredto(sal_uLong nNode) : mnNode(nNode) {}
145  bool operator()(const ww8::Frame &rFrame) const
146  {
147  return (mnNode == rFrame.GetPosition().nNode.GetNode().GetIndex());
148  }
149  };
150 }
151 
152 namespace ww8
153 {
154  //For i120928,size conversion before exporting graphic of bullet
155  Frame::Frame(const Graphic &rGrf, const SwPosition &rPos)
156  : mpFlyFrame(nullptr)
157  , maPos(rPos)
158  , maSize()
159  , maLayoutSize()
160  , meWriterType(eBulletGrf)
161  , mpStartFrameContent(nullptr)
162  , mbIsInline(true)
163  , mbForBullet(true)
164  , maGrf(rGrf)
165  {
166  const MapMode aMap100mm( MapUnit::Map100thMM );
167  Size aSize( rGrf.GetPrefSize() );
168  if ( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
169  {
170  aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap100mm );
171  }
172  else
173  {
174  aSize = OutputDevice::LogicToLogic( aSize,rGrf.GetPrefMapMode(), aMap100mm );
175  }
176  maSize = aSize;
178  }
179 
180  Frame::Frame(const SwFrameFormat &rFormat, const SwPosition &rPos)
181  : mpFlyFrame(&rFormat)
182  , maPos(rPos)
183  , maSize()
184  , maLayoutSize() // #i43447#
185  , meWriterType(eTextBox)
186  , mpStartFrameContent(nullptr)
187  // #i43447# - move to initialization list
188  , mbIsInline( (rFormat.GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) )
189  // #i120928# - handle graphic of bullet within existing implementation
190  , mbForBullet(false)
191  , maGrf()
192  {
193  switch (rFormat.Which())
194  {
195  case RES_FLYFRMFMT:
196  if (const SwNodeIndex* pIdx = rFormat.GetContent().GetContentIdx())
197  {
198  SwNodeIndex aIdx(*pIdx, 1);
199  const SwNode &rNd = aIdx.GetNode();
200  // #i43447# - determine layout size
201  {
202  SwRect aLayRect( rFormat.FindLayoutRect() );
203  tools::Rectangle aRect( aLayRect.SVRect() );
204  // The Object is not rendered (e.g. something in unused
205  // header/footer) - thus, get the values from the format.
206  if ( aLayRect.IsEmpty() )
207  {
208  aRect.SetSize( rFormat.GetFrameSize().GetSize() );
209  }
210  maLayoutSize = aRect.GetSize();
211  }
212  switch (rNd.GetNodeType())
213  {
214  case SwNodeType::Grf:
216  maSize = rNd.GetNoTextNode()->GetTwipSize();
217  break;
218  case SwNodeType::Ole:
219  meWriterType = eOle;
220  maSize = rNd.GetNoTextNode()->GetTwipSize();
221  break;
222  default:
224  // #i43447# - Size equals layout size for text boxes
226  break;
227  }
228  mpStartFrameContent = &rNd;
229  }
230  else
231  {
232  OSL_ENSURE(false, "Impossible");
234  }
235  break;
236  default:
237  if (const SdrObject* pObj = rFormat.FindRealSdrObject())
238  {
239  if (pObj->GetObjInventor() == SdrInventor::FmForm)
241  else
243  maSize = pObj->GetSnapRect().GetSize();
245  }
246  else
247  {
248  OSL_ENSURE(false, "Impossible");
250  }
251  break;
252  }
253  }
254 
255 
257  {
258  mbIsInline = true;
259  }
260 }
261 
262 namespace sw
263 {
264  namespace hack
265  {
266 
267  sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool,
268  const SfxItemPool &rSrcPool, sal_uInt16 nWhich)
269  {
270  sal_uInt16 nSlotId = rSrcPool.GetSlotId(nWhich);
271  if (IsValidSlotWhich(nSlotId, nWhich))
272  nWhich = rDestPool.GetWhich(nSlotId);
273  else
274  nWhich = 0;
275  return nWhich;
276  }
277 
278  sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
279  const SwDoc &rDoc, sal_uInt16 nWhich)
280  {
281  if (RES_WHICHHINT_END < *(rSet.GetRanges()))
282  {
283  nWhich = TransformWhichBetweenPools(*rSet.GetPool(),
284  rDoc.GetAttrPool(), nWhich);
285  }
286  return nWhich;
287  }
288 
290  SfxObjectShell &rPers)
291  : mxIPRef(rObj.GetObjRef()), mrPers(rPers),
292  mpGraphic( rObj.GetGraphic() )
293  {
294  rObj.AbandonObject();
295  }
296 
297  bool DrawingOLEAdaptor::TransferToDoc( OUString &rName )
298  {
299  OSL_ENSURE(mxIPRef.is(), "Transferring invalid object to doc");
300  if (!mxIPRef.is())
301  return false;
302 
303  uno::Reference < container::XChild > xChild( mxIPRef, uno::UNO_QUERY );
304  if ( xChild.is() )
305  xChild->setParent( mrPers.GetModel() );
306 
308  if (bSuccess)
309  {
310  if ( mpGraphic )
313  rName,
314  OUString() );
315 
316  mxIPRef = nullptr;
317  }
318 
319  return bSuccess;
320  }
321 
323  {
324  if (mxIPRef.is())
325  {
326  OSL_ENSURE( !mrPers.GetEmbeddedObjectContainer().HasEmbeddedObject( mxIPRef ), "Object in adaptor is inserted?!" );
327  try
328  {
329  uno::Reference < css::util::XCloseable > xClose( mxIPRef, uno::UNO_QUERY );
330  if ( xClose.is() )
331  xClose->close(true);
332  }
333  catch ( const css::util::CloseVetoException& )
334  {
335  }
336 
337  mxIPRef = nullptr;
338  }
339  }
340  }
341 
342  namespace util
343  {
345  {
346  if (nIn > SHRT_MAX)
347  nIn = SHRT_MAX;
348  else if (nIn < SHRT_MIN)
349  nIn = SHRT_MIN;
350  return nIn;
351  }
352 
354  {
355  SetObjectLayer(rObject, eHell);
356  }
357 
359  {
360  SetObjectLayer(rObject, eHeaven);
361  }
362 
363  void SetLayer::SetObjectLayer(SdrObject &rObject, Layer eLayer) const
364  {
365  if (SdrInventor::FmForm == rObject.GetObjInventor())
366  rObject.SetLayer(mnFormLayer);
367  else
368  {
369  switch (eLayer)
370  {
371  case eHeaven:
372  rObject.SetLayer(mnHeavenLayer);
373  break;
374  case eHell:
375  rObject.SetLayer(mnHellLayer);
376  break;
377  }
378  }
379  }
380 
381  //SetLayer boilerplate begin
382 
383  // #i38889# - by default put objects into the invisible layers.
385  : mnHeavenLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleHeavenId()),
386  mnHellLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleHellId()),
387  mnFormLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleControlsId())
388  {
389  }
390  //SetLayer boilerplate end
391 
392  void GetPoolItems(const SfxItemSet &rSet, ww8::PoolItems &rItems, bool bExportParentItemSet )
393  {
394  if( bExportParentItemSet )
395  {
396  sal_uInt16 nTotal = rSet.TotalCount();
397  for( sal_uInt16 nItem =0; nItem < nTotal; ++nItem )
398  {
399  const SfxPoolItem* pItem = nullptr;
400  if( SfxItemState::SET == rSet.GetItemState( rSet.GetWhichByPos( nItem ), true, &pItem ) )
401  {
402  rItems[pItem->Which()] = pItem;
403  }
404  }
405  }
406  else if( rSet.Count())
407  {
408  SfxItemIter aIter(rSet);
409  if (const SfxPoolItem *pItem = aIter.GetCurItem())
410  {
411  do
412  rItems[pItem->Which()] = pItem;
413  while (!aIter.IsAtEnd() && nullptr != (pItem = aIter.NextItem()));
414  }
415  }
416  }
417 
419  sal_uInt16 eType)
420  {
421  auto aIter = rItems.find(eType);
422  if (aIter != rItems.end())
423  return aIter->second;
424  return nullptr;
425  }
426 
428  {
429  if (const SwCharFormat* pCharFormat = rFormat.GetCharFormat())
430  {
431  if (pCharFormat->GetAttrSet().Count())
432  {
433  SfxItemIter aIter(pCharFormat->GetAttrSet());
434  const SfxPoolItem *pItem = aIter.GetCurItem();
435  do
436  rSet.ClearItem(pItem->Which());
437  while (!aIter.IsAtEnd() && nullptr != (pItem = aIter.NextItem()));
438  }
439  }
440  }
441 
443  {
444  ww8::ParaStyles aStyles;
445  typedef ww8::ParaStyles::size_type mysizet;
446 
447  const SwTextFormatColls *pColls = rDoc.GetTextFormatColls();
448  mysizet nCount = pColls ? pColls->size() : 0;
449  aStyles.reserve(nCount);
450  for (mysizet nI = 0; nI < nCount; ++nI)
451  aStyles.push_back((*pColls)[ static_cast< sal_uInt16 >(nI) ]);
452  return aStyles;
453  }
454 
455  SwTextFormatColl* GetParaStyle(SwDoc &rDoc, const OUString& rName)
456  {
457  // Search first in the Doc-Styles
458  SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName(rName);
459  if (!pColl)
460  {
461  // Collection not found, try in Pool ?
462  sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
464  if (n != SAL_MAX_UINT16) // found or standard
465  pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool(n, false);
466  }
467  return pColl;
468  }
469 
470  SwCharFormat* GetCharStyle(SwDoc &rDoc, const OUString& rName)
471  {
472  SwCharFormat *pFormat = rDoc.FindCharFormatByName(rName);
473  if (!pFormat)
474  {
475  // Collection not found, try in Pool ?
476  sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
478  if (n != SAL_MAX_UINT16) // found or standard
480  }
481  return pFormat;
482  }
483 
484  // #i98791# - adjust sorting algorithm
486  {
487  std::sort(rStyles.begin(), rStyles.end(), outlinecmp());
488  }
489 
490  /*
491  Utility to extract FlyFormats from a document, potentially from a
492  selection.
493  */
494  ww8::Frames GetFrames(const SwDoc &rDoc, SwPaM const *pPaM /*, bool bAll*/)
495  {
496  SwPosFlyFrames aFlys(rDoc.GetAllFlyFormats(pPaM, true));
497  ww8::Frames aRet(SwPosFlyFramesToFrames(aFlys));
498  return aRet;
499  }
500 
502  {
503  for (ww8::Frame & rFrame : rFrames)
504  {
505  SwFormatAnchor const& rAnchor = rFrame.GetFrameFormat().GetAnchor();
506  if (SwPosition const*const pAnchor = rAnchor.GetContentAnchor())
507  {
508  rFrame.SetPosition(*pAnchor);
509  }
510  else
511  { // these don't need to be corrected, they're not in redlines
512  assert(RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId());
513  }
514  }
515  }
516 
517  ww8::Frames GetFramesInNode(const ww8::Frames &rFrames, const SwNode &rNode)
518  {
519  ww8::Frames aRet;
520  std::copy_if(rFrames.begin(), rFrames.end(),
521  std::back_inserter(aRet), anchoredto(rNode.GetIndex()));
522  return aRet;
523  }
524 
526  int nLevel)
527  {
528  if (nLevel < 0 || nLevel >= MAXLEVEL)
529  {
530  OSL_FAIL("Invalid level");
531  return nullptr;
532  }
533  return &(rRule.Get( static_cast< sal_uInt16 >(nLevel) ));
534  }
535 
537  {
538  const SwNumRule *pRule = nullptr;
539  if (
540  rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
541  nullptr != (pRule = rTextNode.GetNumRule())
542  )
543  {
544  return GetNumFormatFromSwNumRuleLevel(*pRule,
545  rTextNode.GetActualListLevel());
546  }
547 
548  OSL_ENSURE(rTextNode.GetDoc(), "No document for node?, suspicious");
549  if (!rTextNode.GetDoc())
550  return nullptr;
551 
552  if (
553  rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
554  nullptr != (pRule = rTextNode.GetDoc()->GetOutlineNumRule())
555  )
556  {
557  return GetNumFormatFromSwNumRuleLevel(*pRule,
558  rTextNode.GetActualListLevel());
559  }
560 
561  return nullptr;
562  }
563 
564  const SwNumRule* GetNumRuleFromTextNode(const SwTextNode &rTextNode)
565  {
566  return GetNormalNumRuleFromTextNode(rTextNode);
567  }
568 
570  {
571  const SwNumRule *pRule = nullptr;
572 
573  if (
574  rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
575  nullptr != (pRule = rTextNode.GetNumRule())
576  )
577  {
578  return pRule;
579  }
580  return nullptr;
581  }
582 
584  {
585  const SwNodeIndex *pIndex = rFormat.GetContent().GetContentIdx();
586  OSL_ENSURE(pIndex, "No NodeIndex in SwFrameFormat ?, suspicious");
587  if (!pIndex)
588  return nullptr;
589  SwNodeIndex aIdx(*pIndex, 1);
590  return aIdx.GetNode().GetNoTextNode();
591  }
592 
593  bool HasPageBreak(const SwNode &rNd)
594  {
595  const SvxFormatBreakItem *pBreak = nullptr;
596  if (rNd.IsTableNode() && rNd.GetTableNode())
597  {
598  const SwTable& rTable = rNd.GetTableNode()->GetTable();
599  const SwFrameFormat* pApply = rTable.GetFrameFormat();
600  OSL_ENSURE(pApply, "impossible");
601  if (pApply)
602  pBreak = &(ItemGet<SvxFormatBreakItem>(*pApply, RES_BREAK));
603  }
604  else if (const SwContentNode *pNd = rNd.GetContentNode())
605  pBreak = &(ItemGet<SvxFormatBreakItem>(*pNd, RES_BREAK));
606 
607  return pBreak && pBreak->GetBreak() == SvxBreak::PageBefore;
608  }
609 
611  {
612  if(1 == rPolyPoly.Count())
613  {
614  return rPolyPoly[0];
615  }
616  else
617  {
618  // This method will now just concatenate the polygons contained
619  // in the given PolyPolygon. Anything else which might be thought of
620  // for reducing to a single polygon will just need nore power and
621  // cannot create more correct results.
622  sal_uInt32 nPointCount(0);
623  sal_uInt16 a;
624 
625  for(a = 0; a < rPolyPoly.Count(); a++)
626  {
627  nPointCount += static_cast<sal_uInt32>(rPolyPoly[a].GetSize());
628  }
629 
630  if(nPointCount > 0x0000ffff)
631  {
632  OSL_FAIL("PolygonFromPolyPolygon: too many points for a single polygon (!)");
633  nPointCount = 0x0000ffff;
634  }
635 
636  tools::Polygon aRetval(static_cast<sal_uInt16>(nPointCount));
637  sal_uInt32 nAppendIndex(0);
638 
639  for(a = 0; a < rPolyPoly.Count(); a++)
640  {
641  const tools::Polygon& rCandidate = rPolyPoly[a];
642 
643  for(sal_uInt16 b(0); nAppendIndex <= nPointCount && b < rCandidate.GetSize(); b++)
644  {
645  aRetval[static_cast<sal_uInt16>(nAppendIndex++)] = rCandidate[b];
646  }
647  }
648 
649  return aRetval;
650  }
651  }
652 
654  {
655  tools::Polygon aPoly(PolygonFromPolyPolygon(rPolyPoly));
656  const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
657  Fraction aMapPolyX(ww::nWrap100Percent, rOrigSize.Width());
658  Fraction aMapPolyY(ww::nWrap100Percent, rOrigSize.Height());
659  aPoly.Scale(double(aMapPolyX), double(aMapPolyY));
660 
661  /*
662  a) stretch right bound by 15twips
663  b) shrink bottom bound to where it would have been in word
664  c) Move it to the left by 15twips
665 
666  See the import for details
667  */
668  const Size &rSize = pNd->GetTwipSize();
669  Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
670  aMoveHack *= Fraction(15, 1);
671  long nMove(aMoveHack);
672 
673  Fraction aHackX(ww::nWrap100Percent + nMove,
675  Fraction aHackY(ww::nWrap100Percent - nMove,
677  aPoly.Scale(double(aHackX), double(aHackY));
678 
679  aPoly.Move(-nMove, 0);
680  return aPoly;
681  }
682 
683  void RedlineStack::open(const SwPosition& rPos, const SfxPoolItem& rAttr)
684  {
685  OSL_ENSURE(rAttr.Which() == RES_FLTR_REDLINE, "not a redline");
686  maStack.emplace_back(new SwFltStackEntry(rPos, std::unique_ptr<SfxPoolItem>(rAttr.Clone())));
687  }
688 
690  {
691  private:
693  public:
694  explicit SameOpenRedlineType(RedlineType_t eType) : meType(eType) {}
695  bool operator()(const std::unique_ptr<SwFltStackEntry> & pEntry) const
696  {
697  const SwFltRedline *pTest = static_cast<const SwFltRedline *>
698  (pEntry->pAttr.get());
699  return (pEntry->bOpen && (pTest->eType == meType));
700  }
701  };
702 
704  {
705  //Search from end for same type
706  auto aResult = std::find_if(maStack.rbegin(), maStack.rend(),
707  SameOpenRedlineType(eType));
708  if (aResult != maStack.rend())
709  {
710  SwTextNode *const pNode(rPos.nNode.GetNode().GetTextNode());
711  sal_Int32 const nIndex(rPos.nContent.GetIndex());
712  // HACK to prevent overlap of field-mark and redline,
713  // which would destroy field-mark invariants when the redline
714  // is hidden: move the redline end one to the left
715  if (pNode && nIndex > 0
716  && pNode->GetText()[nIndex - 1] == CH_TXT_ATR_FIELDEND)
717  {
718  SwPosition const end(*rPos.nNode.GetNode().GetTextNode(),
719  nIndex - 1);
720  sw::mark::IFieldmark *const pFieldMark(
722  SAL_WARN_IF(!pFieldMark, "sw.ww8", "expected a field mark");
723  if (pFieldMark && pFieldMark->GetMarkPos().nNode.GetIndex() == (*aResult)->m_aMkPos.m_nNode.GetIndex()+1
724  && pFieldMark->GetMarkPos().nContent.GetIndex() < (*aResult)->m_aMkPos.m_nContent)
725  {
726  (*aResult)->SetEndPos(end);
727  return true;
728  }
729  }
730  (*aResult)->SetEndPos(rPos);
731  return true;
732  }
733  return false;
734  }
735 
737  {
738  std::for_each(maStack.begin(), maStack.end(), SetEndIfOpen(rPos));
739  }
740 
742  {
743  size_t nCnt = maStack.size();
744  sal_uLong nPosNd = rPos.nNode.GetIndex();
745  sal_Int32 nPosCt = rPos.nContent.GetIndex() - 1;
746 
747  for (size_t i=0; i < nCnt; ++i)
748  {
749  SwFltStackEntry& rEntry = *maStack[i];
750  bool const isPoint(rEntry.m_aMkPos == rEntry.m_aPtPos);
751  if ((rEntry.m_aMkPos.m_nNode.GetIndex()+1 == nPosNd) &&
752  (nPosCt <= rEntry.m_aMkPos.m_nContent))
753  {
754  rEntry.m_aMkPos.m_nContent++;
755  SAL_WARN_IF(rEntry.m_aMkPos.m_nContent > rPos.nNode.GetNodes()[nPosNd]->GetContentNode()->Len(),
756  "sw.ww8", "redline ends after end of line");
757  if (isPoint) // sigh ... important special case...
758  {
759  rEntry.m_aPtPos.m_nContent++;
760  continue;
761  }
762  }
763  // for the end position, leave it alone if it's *on* the dummy
764  // char position, that should remain *before*
765  if ((rEntry.m_aPtPos.m_nNode.GetIndex()+1 == nPosNd) &&
766  (nPosCt < rEntry.m_aPtPos.m_nContent))
767  {
768  rEntry.m_aPtPos.m_nContent++;
769  SAL_WARN_IF(rEntry.m_aPtPos.m_nContent > rPos.nNode.GetNodes()[nPosNd]->GetContentNode()->Len(),
770  "sw.ww8", "redline ends after end of line");
771  }
772  }
773  }
774 
775  void SetInDocAndDelete::operator()(std::unique_ptr<SwFltStackEntry>& pEntry)
776  {
777  SwPaM aRegion(pEntry->m_aMkPos.m_nNode);
778  if (
779  pEntry->MakeRegion(&mrDoc, aRegion, true) &&
780  (*aRegion.GetPoint() != *aRegion.GetMark())
781  )
782  {
785  const SwFltRedline *pFltRedline = static_cast<const SwFltRedline*>
786  (pEntry->pAttr.get());
787 
788  if (SwFltRedline::NoPrevAuthor != pFltRedline->nAutorNoPrev)
789  {
790  SwRedlineData aData(pFltRedline->eTypePrev,
791  pFltRedline->nAutorNoPrev, pFltRedline->aStampPrev, OUString(),
792  nullptr);
793 
794  mrDoc.getIDocumentRedlineAccess().AppendRedline(new SwRangeRedline(aData, aRegion), true);
795  }
796 
797  SwRedlineData aData(pFltRedline->eType, pFltRedline->nAutorNo,
798  pFltRedline->aStamp, OUString(), nullptr);
799 
800  SwRangeRedline *const pNewRedline(new SwRangeRedline(aData, aRegion));
801  // the point node may be deleted in AppendRedline, so park
802  // the PaM somewhere safe
803  aRegion.DeleteMark();
804  *aRegion.GetPoint() = SwPosition(SwNodeIndex(mrDoc.GetNodes()));
805  mrDoc.getIDocumentRedlineAccess().AppendRedline(pNewRedline, true);
808  }
809  pEntry.reset();
810  }
811 
812  bool CompareRedlines::operator()(const std::unique_ptr<SwFltStackEntry> & pOneE,
813  const std::unique_ptr<SwFltStackEntry> & pTwoE) const
814  {
815  const SwFltRedline *pOne= static_cast<const SwFltRedline*>
816  (pOneE->pAttr.get());
817  const SwFltRedline *pTwo= static_cast<const SwFltRedline*>
818  (pTwoE->pAttr.get());
819 
820  //Return the earlier time, if two have the same time, prioritize
821  //inserts over deletes
822  if (pOne->aStamp == pTwo->aStamp)
824  else
825  return (pOne->aStamp < pTwo->aStamp);
826  }
827 
829  {
830  std::sort(maStack.begin(), maStack.end(), CompareRedlines());
831  std::for_each(maStack.begin(), maStack.end(), SetInDocAndDelete(mrDoc));
832  }
833 
834  sal_uInt16 WrtRedlineAuthor::AddName( const OUString& rNm )
835  {
836  sal_uInt16 nRet;
837  auto aIter = std::find(maAuthors.begin(), maAuthors.end(), rNm);
838  if (aIter != maAuthors.end())
839  nRet = static_cast< sal_uInt16 >(aIter - maAuthors.begin());
840  else
841  {
842  nRet = static_cast< sal_uInt16 >(maAuthors.size());
843  maAuthors.push_back(rNm);
844  }
845  return nRet;
846  }
847  }
848 
849  namespace util
850  {
852  {
853  rNode.Add(this);
854  }
855 
857  {
858  return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst());
859  }
860 
862  : mbHasRoot(rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
863  {
864  }
865 
867  {
868  if (!mbHasRoot)
869  return;
870  for (auto& aTable : maTables)
871  {
872  // If already a layout exists, then the BoxFrames must recreated at this table
873  SwTableNode *pTable = aTable.first->GetTableNode();
874  OSL_ENSURE(pTable, "Why no expected table");
875  if (pTable)
876  {
877  SwFrameFormat * pFrameFormat = pTable->GetTable().GetFrameFormat();
878 
879  if (pFrameFormat != nullptr)
880  {
881  SwNodeIndex *pIndex = aTable.second;
882  pTable->DelFrames();
883  pTable->MakeOwnFrames(pIndex);
884  }
885  }
886  }
887  }
888 
890  {
891  if (!mbHasRoot)
892  return;
893  //Associate this tablenode with this after position, replace an //old
894  //node association if necessary
895 
896  InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
897 
898  maTables.emplace(pClient, &(rPaM.GetPoint()->nNode));
899  }
900  }
901 
902 }
903 
904 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool TransferToDoc(OUString &rName)
Transfer ownership of the OLE object to a document's SvPersist.
virtual SwCharFormat * GetCharFormatFromPool(sal_uInt16 nId)=0
sal_uInt16 Count() const
Graphic GetGraphic() const
Definition: ndnotxt.cxx:231
long Width() const
std::set< SwPosFlyFramePtr, SwPosFlyFrameCmp > SwPosFlyFrames
Definition: flypos.hxx:51
void DeleteMark()
Definition: pam.hxx:177
sal_uLong GetIndex() const
Definition: node.hxx:282
SwNoTextNode * GetNoTextNodeFromSwFrameFormat(const SwFrameFormat &rFormat)
Get the SwNoTextNode associated with a SwFrameFormat if here is one.
void Add(SwClient *pDepend)
Definition: calbck.cxx:217
int GetAssignedOutlineStyleLevel() const
Definition: fmtcol.cxx:588
InsertedTablesManager(const SwDoc &rDoc)
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
Marks a position in the document model.
Definition: pam.hxx:35
ww8::Frames GetFramesInNode(const ww8::Frames &rFrames, const SwNode &rNode)
Get the Frames anchored to a given node.
const SfxPoolItem * SearchPoolItems(const ww8::PoolItems &rItems, sal_uInt16 eType)
void DelFrames(SwRootFrame const *pLayout=nullptr)
Method deletes all views of document for the node.
Definition: ndtbl.cxx:2415
void closeall(const SwPosition &rPos)
Frame(const SwFrameFormat &rFlyFrame, const SwPosition &rPos)
RedlineType_t const eType
Definition: fltshell.hxx:220
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
SwNodeIndex m_nNode
Definition: fltshell.hxx:55
virtual AppendResult AppendRedline(SwRangeRedline *pNewRedl, bool bCallDelete)=0
Append a new redline.
bool operator()(const std::unique_ptr< SwFltStackEntry > &pOneE, const std::unique_ptr< SwFltStackEntry > &pTwoE) const
long Height() const
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
SwNodeIndex nNode
Definition: pam.hxx:37
SvxBreak GetBreak() const
SwTextFormatColl * FindTextFormatCollByName(const OUString &rName) const
Definition: doc.hxx:794
virtual Size GetTwipSize() const =0
sal_uIntPtr sal_uLong
#define RES_FLTR_REDLINE
Definition: hintids.hxx:325
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2633
const SwPosition * GetMark() const
Definition: pam.hxx:209
InsertedTableClient(SwTableNode &rNode)
Definition: doc.hxx:185
bool HasEmbeddedObject(const OUString &)
sal_uInt16 AddName(const OUString &rNm)
DateTime const aStampPrev
Definition: fltshell.hxx:219
SwNode & GetNode() const
Definition: ndindex.hxx:118
bool IsAtEnd() const
long SwTwips
Definition: swtypes.hxx:49
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1348
Dialog to specify the properties of drop-down form field.
Definition: accframe.hxx:34
tools::Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon &rPolyPoly, const SwNoTextNode *pNd)
Undo all scaling / move tricks of the wrap polygon done during import.
css::uno::Reference< css::frame::XModel > GetModel() const
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
std::vector< OUString > maAuthors
Definition: msfilter.hxx:348
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4097
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:201
tools::Polygon PolygonFromPolyPolygon(const tools::PolyPolygon &rPolyPoly)
Make a best fit Polygon from a PolyPolygon.
SwPosFlyFrames GetAllFlyFormats(const SwPaM *, bool bDrawAlso, bool bAsCharAlso=false) const
Returns positions of all FlyFrames in the document.
Definition: doclay.cxx:516
void Scale(double fScaleX, double fScaleY)
const int nWrap100Percent
For custom wrapping.
Definition: types.hxx:38
show all inserts
void GetPoolItems(const SfxItemSet &rSet, ww8::PoolItems &rItems, bool bExportParentItemSet)
Get the SfxPoolItems of a SfxItemSet.
~DrawingOLEAdaptor()
Destructor will destroy the owned OLE object if not transferred.
SdrLayerID mnFormLayer
static OutputDevice * GetDefaultDevice()
bool IsAssignedToListLevelOfOutlineStyle() const
Definition: fmtcol.hxx:109
SwTableNode * GetTableNode()
Definition: node.hxx:599
SwNodeType GetNodeType() const
Definition: node.hxx:144
SwIndex nContent
Definition: pam.hxx:38
SwDoc * GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:178
#define SAL_MAX_UINT16
SetLayer(const SwDoc &rDoc)
Normal constructor.
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:458
void open(const SwPosition &rPos, const SfxPoolItem &rAttr)
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
static SW_DLLPUBLIC sal_uInt16 GetPoolIdFromUIName(const OUString &rName, SwGetPoolIdFromName)
void InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
const SwTable & GetTable() const
Definition: node.hxx:497
const SwNumRule * GetNumRuleFromTextNode(const SwTextNode &rTextNode)
RedlineFlags on.
static constexpr auto NoPrevAuthor
Definition: fltshell.hxx:226
bool operator()(const std::unique_ptr< SwFltStackEntry > &pEntry) const
const SwFrameFormat & GetFrameFormat() const
Get the writer SwFrameFormat that this object describes.
void SendObjectToHeaven(SdrObject &rObject) const
Make Object lives in the top layer.
#define RES_FLYFRMFMT
Definition: hintids.hxx:274
void MoveAttrs(const SwPosition &rPos)
SdrLayerID mnHellLayer
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void Move(long nHorzMove, long nVertMove)
virtual void SetLayer(SdrLayerID nLayer)
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
bool HasPageBreak(const SwNode &rNd)
Does a node have a "page break before" applied.
Style of a layout element.
Definition: frmfmt.hxx:57
void UpdateFramePositions(ww8::Frames &rFrames)
fix up frame positions, must be called after SetRedlineFlags
SameOpenRedlineType(RedlineType_t eType)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
std::map< sal_uInt16, const SfxPoolItem *, sw::util::ItemSort > PoolItems
STL container of SfxPoolItems (Attributes)
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
const SwPosition * GetPoint() const
Definition: pam.hxx:207
SwTwips MakeSafePositioningValue(SwTwips nIn)
Clips a value to MAX/MIN 16bit value to make it safe for use as a position value to give to writer...
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
void SortByAssignedOutlineStyleListLevel(ww8::ParaStyles &rStyles)
Sort sequence of Paragraph Styles by assigned outline style list level.
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
static void SetGraphicToContainer(const Graphic &rGraphic, comphelper::EmbeddedObjectContainer &aContainer, const OUString &aName, const OUString &aMediaType)
void SetSize(const Size &rSize)
int i
SwContentNode * GetContentNode()
Definition: node.hxx:615
RedlineType_t const meType
FlyAnchors.
Definition: fmtanchr.hxx:34
sal_uInt16 Count() const
const SfxPoolItem * NextItem()
SwNoTextNode * GetNoTextNode()
Definition: ndnotxt.hxx:96
std::vector< std::unique_ptr< SwFltStackEntry > > maStack
Definition: msfilter.hxx:295
css::ui::LayoutSize maLayoutSize
SwDoc * GetDoc()
Definition: node.hxx:702
size_t size() const
Definition: docary.hxx:90
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2814
void MakeOwnFrames(SwNodeIndex *pIdxBehind)
Creates the frms for the table node (i.e. the TabFrames).
Definition: ndtbl.cxx:2376
sal_uInt16 GetSize() const
Marks a node in the document model.
Definition: ndindex.hxx:31
const SwNumRule * GetNormalNumRuleFromTextNode(const SwTextNode &rTextNode)
void ForceTreatAsInline()
Even if the frame isn't an inline frame, force it to behave as one.
void SetPosition(SwPosition const &rPos)
void SetObjectLayer(SdrObject &rObject, Layer eLayer) const
MapUnit GetMapUnit() const
sal_uInt16 GetSlotId(sal_uInt16 nWhich) const
GUIDCNamePair const aData
sal_uInt16 GetWhichByPos(sal_uInt16 nPos) const
sal_Int32 m_nContent
Definition: fltshell.hxx:56
sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool, const SfxItemPool &rSrcPool, sal_uInt16 nWhich)
Map an ID valid in one SfxItemPool to its equivalent in another.
SfxItemPool * GetPool() const
show all deletes
SwFltPosition m_aMkPos
Definition: fltshell.hxx:90
enumrange< T >::Iterator end(enumrange< T >)
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:110
virtual SdrInventor GetObjInventor() const
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
Point PixelToLogic(const Point &rDevicePt) const
Size GetPrefSize() const
SwTextFormatColl * GetParaStyle(SwDoc &rDoc, const OUString &rName)
Get a Paragraph Style which fits a given name.
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:78
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:83
const RedlineType_t REDLINE_INSERT
SwCharFormat * FindCharFormatByName(const OUString &rName) const
Definition: doc.hxx:766
#define RES_WHICHHINT_END
Definition: hintids.hxx:336
Size maLayoutSize
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
SwFltPosition m_aPtPos
Definition: fltshell.hxx:91
comphelper::EmbeddedObjectContainer & GetEmbeddedObjectContainer() const
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
SwCharFormat * GetCharFormat() const
Definition: fchrfmt.hxx:70
sal_uInt16 RedlineType_t
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
#define SAL_WARN_IF(condition, area, stream)
const SwTextFormatColls * GetTextFormatColls() const
Definition: doc.hxx:773
MapMode GetPrefMapMode() const
const SwNodes & GetNodes() const
Definition: ndindex.hxx:155
Make exporting a Writer Frame easy.
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2889
std::size_t const nAutorNo
Definition: fltshell.hxx:222
DrawingOLEAdaptor(SdrOle2Obj &rObj, SfxObjectShell &rPers)
Take ownership of a SdrOle2Objs OLE object.
virtual void SetRedlineFlags(RedlineFlags eMode)=0
Set a new redline mode.
sal_Int32 GetIndex() const
Definition: index.hxx:95
bool IsCountedInList() const
Definition: ndtxt.cxx:4240
ww8::ParaStyles GetParaStyles(const SwDoc &rDoc)
Get the Paragraph Styles of a SwDoc.
sal_uInt16 TotalCount() const
SwNodes & GetNodes()
Definition: doc.hxx:403
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
css::uno::Reference< css::embed::XEmbeddedObject > mxIPRef
WriterSource meWriterType
RedlineType_t const eTypePrev
Definition: fltshell.hxx:221
void AbandonObject()
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:53
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
bool InsertEmbeddedObject(const css::uno::Reference< css::embed::XEmbeddedObject > &, OUString &)
const SwNode * mpStartFrameContent
ww8::Frames GetFrames(const SwDoc &rDoc, SwPaM const *pPaM)
Get the Floating elements in a SwDoc.
const SwNumFormat * GetNumFormatFromTextNode(const SwTextNode &rTextNode)
Get the Numbering Format used on a paragraph.
void operator()(std::unique_ptr< SwFltStackEntry > &pEntry)
const sal_uInt16 * GetRanges() const
SwModify * GetRegisteredInNonConst() const
Definition: calbck.hxx:134
RndStdIds
bool IsTableNode() const
Definition: node.hxx:640
void SendObjectToHell(SdrObject &rObject) const
Make Object live in the bottom drawing layer.
SdrLayerID mnHeavenLayer
DateTime const aStamp
Definition: fltshell.hxx:218
const SwNumFormat * GetNumFormatFromSwNumRuleLevel(const SwNumRule &rRule, int nLevel)
Get the Numbering Format for a given level from a numbering rule.
sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet, const SwDoc &rDoc, sal_uInt16 nWhich)
Map a SwDoc WhichId to the equivalent Id for a given SfxItemSet.
std::vector< SwTextFormatColl * > ParaStyles
STL container of Paragraph Styles (SwTextFormatColl)
void ClearOverridesFromSet(const SwFormatCharFormat &rFormat, SfxItemSet &rSet)
Remove properties from an SfxItemSet which a SwFormatCharFormat overrides.
#define RES_BREAK
Definition: hintids.hxx:199
SwCharFormat * GetCharStyle(SwDoc &rDoc, const OUString &rName)
Get a Character Style which fits a given name.
bool close(const SwPosition &rPos, RedlineType_t eType)
const SwPosition & GetPosition() const
Get the position this frame is anchored at.
sal_uInt16 Which() const
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2686
no RedlineFlags
const Size & GetSize() const
const SfxPoolItem * GetCurItem() const
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1307
std::vector< Frame > Frames
STL container of Frames.
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:842
::basegfx::B2IVector maSize
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1013
std::size_t const nAutorNoPrev
Definition: fltshell.hxx:223
Base class of the Writer document model elements.
Definition: node.hxx:79