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 <redline.hxx>
52 #include "types.hxx"
53 #include <unotools/streamwrap.hxx>
54 #include <svtools/embedhlp.hxx>
55 #include <numrule.hxx>
56 #include <vcl/svapp.hxx>
60 #include <IDocumentMarkAccess.hxx>
61 #include <IMark.hxx>
62 
63 using namespace com::sun::star;
64 
65 namespace
66 {
67  // #i98791# - adjust sorting
68  // Utility to sort SwTextFormatColl's by their assigned outline style list level
69  class outlinecmp
70  {
71  public:
72  bool operator()(const SwTextFormatColl *pA, const SwTextFormatColl *pB) const
73  {
74  // #i98791#
75  bool bResult( false );
76  const bool bIsAAssignedToOutlineStyle( pA->IsAssignedToListLevelOfOutlineStyle() );
77  const bool bIsBAssignedToOutlineStyle( pB->IsAssignedToListLevelOfOutlineStyle() );
78  if ( bIsAAssignedToOutlineStyle != bIsBAssignedToOutlineStyle )
79  {
80  bResult = bIsBAssignedToOutlineStyle;
81  }
82  else if ( !bIsAAssignedToOutlineStyle )
83  {
84  // pA and pB are equal regarding the sorting criteria.
85  // Thus return value does not matter.
86  bResult = false;
87  }
88  else
89  {
91  }
92 
93  return bResult;
94  }
95  };
96 
97  bool IsValidSlotWhich(sal_uInt16 nSlotId, sal_uInt16 nWhichId)
98  {
99  return (nSlotId != 0 && nWhichId != 0 && nSlotId != nWhichId);
100  }
101 
102  /*
103  Utility to convert a SwPosFlyFrames into a simple vector of ww8::Frames
104 
105  The crucial thing is that a ww8::Frame always has an anchor which
106  points to some content in the document. This is a requirement of exporting
107  to Word
108  */
109  ww8::Frames SwPosFlyFramesToFrames(const SwPosFlyFrames &rFlys)
110  {
111  ww8::Frames aRet;
112 
113  for(const auto& rpFly : rFlys)
114  {
115  const SwFrameFormat &rEntry = rpFly->GetFormat();
116 
117  if (const SwPosition* pAnchor = rEntry.GetAnchor().GetContentAnchor())
118  {
119  // the anchor position will be invalidated by SetRedlineFlags
120  // so set a dummy position and fix it in UpdateFramePositions
121  SwPosition const dummy(SwNodeIndex(
122  const_cast<SwNodes&>(pAnchor->nNode.GetNodes())));
123  aRet.emplace_back(rEntry, dummy);
124  }
125  else
126  {
127  SwPosition aPos(rpFly->GetNdIndex());
128 
129  if (SwTextNode* pTextNd = aPos.nNode.GetNode().GetTextNode())
130  {
131  aPos.nContent.Assign(pTextNd, 0);
132  }
133 
134  aRet.emplace_back(rEntry, aPos);
135  }
136  }
137  return aRet;
138  }
139 
140  //Utility to test if a frame is anchored at a given node index
141  class anchoredto
142  {
143  private:
144  sal_uLong const mnNode;
145  public:
146  explicit anchoredto(sal_uLong nNode) : mnNode(nNode) {}
147  bool operator()(const ww8::Frame &rFrame) const
148  {
149  return (mnNode == rFrame.GetPosition().nNode.GetNode().GetIndex());
150  }
151  };
152 }
153 
154 namespace ww8
155 {
156  //For i120928,size conversion before exporting graphic of bullet
157  Frame::Frame(const Graphic &rGrf, const SwPosition &rPos)
158  : mpFlyFrame(nullptr)
159  , maPos(rPos)
160  , maSize()
161  , maLayoutSize()
162  , meWriterType(eBulletGrf)
163  , mpStartFrameContent(nullptr)
164  , mbIsInline(true)
165  , mbForBullet(true)
166  , maGrf(rGrf)
167  {
168  const MapMode aMap100mm( MapUnit::Map100thMM );
169  Size aSize( rGrf.GetPrefSize() );
170  if ( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
171  {
172  aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap100mm );
173  }
174  else
175  {
176  aSize = OutputDevice::LogicToLogic( aSize,rGrf.GetPrefMapMode(), aMap100mm );
177  }
178  maSize = aSize;
180  }
181 
182  Frame::Frame(const SwFrameFormat &rFormat, const SwPosition &rPos)
183  : mpFlyFrame(&rFormat)
184  , maPos(rPos)
185  , maSize()
186  , maLayoutSize() // #i43447#
187  , meWriterType(eTextBox)
188  , mpStartFrameContent(nullptr)
189  // #i43447# - move to initialization list
190  , mbIsInline( (rFormat.GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) )
191  // #i120928# - handle graphic of bullet within existing implementation
192  , mbForBullet(false)
193  , maGrf()
194  {
195  switch (rFormat.Which())
196  {
197  case RES_FLYFRMFMT:
198  if (const SwNodeIndex* pIdx = rFormat.GetContent().GetContentIdx())
199  {
200  SwNodeIndex aIdx(*pIdx, 1);
201  const SwNode &rNd = aIdx.GetNode();
202  // #i43447# - determine layout size
203  {
204  SwRect aLayRect( rFormat.FindLayoutRect() );
205  tools::Rectangle aRect( aLayRect.SVRect() );
206  // The Object is not rendered (e.g. something in unused
207  // header/footer) - thus, get the values from the format.
208  if ( aLayRect.IsEmpty() )
209  {
210  aRect.SetSize( rFormat.GetFrameSize().GetSize() );
211  }
212  maLayoutSize = aRect.GetSize();
213  }
214  switch (rNd.GetNodeType())
215  {
216  case SwNodeType::Grf:
218  maSize = rNd.GetNoTextNode()->GetTwipSize();
219  break;
220  case SwNodeType::Ole:
221  meWriterType = eOle;
222  maSize = rNd.GetNoTextNode()->GetTwipSize();
223  break;
224  default:
226  // #i43447# - Size equals layout size for text boxes
228  break;
229  }
230  mpStartFrameContent = &rNd;
231  }
232  else
233  {
234  OSL_ENSURE(false, "Impossible");
236  }
237  break;
238  default:
239  if (const SdrObject* pObj = rFormat.FindRealSdrObject())
240  {
241  if (pObj->GetObjInventor() == SdrInventor::FmForm)
243  else
245  maSize = pObj->GetSnapRect().GetSize();
247  }
248  else
249  {
250  OSL_ENSURE(false, "Impossible");
252  }
253  break;
254  }
255  }
256 
257 
259  {
260  mbIsInline = true;
261  }
262 }
263 
264 namespace sw
265 {
266  namespace hack
267  {
268 
269  sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool,
270  const SfxItemPool &rSrcPool, sal_uInt16 nWhich)
271  {
272  sal_uInt16 nSlotId = rSrcPool.GetSlotId(nWhich);
273  if (IsValidSlotWhich(nSlotId, nWhich))
274  nWhich = rDestPool.GetWhich(nSlotId);
275  else
276  nWhich = 0;
277  return nWhich;
278  }
279 
280  sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
281  const SwDoc &rDoc, sal_uInt16 nWhich)
282  {
283  if (RES_WHICHHINT_END < *(rSet.GetRanges()))
284  {
285  nWhich = TransformWhichBetweenPools(*rSet.GetPool(),
286  rDoc.GetAttrPool(), nWhich);
287  }
288  return nWhich;
289  }
290 
292  SfxObjectShell &rPers)
293  : mxIPRef(rObj.GetObjRef()), mrPers(rPers),
294  mpGraphic( rObj.GetGraphic() )
295  {
296  rObj.AbandonObject();
297  }
298 
299  bool DrawingOLEAdaptor::TransferToDoc( OUString &rName )
300  {
301  OSL_ENSURE(mxIPRef.is(), "Transferring invalid object to doc");
302  if (!mxIPRef.is())
303  return false;
304 
305  uno::Reference < container::XChild > xChild( mxIPRef, uno::UNO_QUERY );
306  if ( xChild.is() )
307  xChild->setParent( mrPers.GetModel() );
308 
310  if (bSuccess)
311  {
312  if ( mpGraphic )
315  rName,
316  OUString() );
317 
318  mxIPRef = nullptr;
319  }
320 
321  return bSuccess;
322  }
323 
325  {
326  if (mxIPRef.is())
327  {
328  OSL_ENSURE( !mrPers.GetEmbeddedObjectContainer().HasEmbeddedObject( mxIPRef ), "Object in adaptor is inserted?!" );
329  try
330  {
331  mxIPRef->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 more 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 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 
703  bool RedlineStack::close(const SwPosition& rPos, RedlineType eType)
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  SwRedlineData aData(pFltRedline->eType, pFltRedline->nAutorNo,
789  pFltRedline->aStamp, OUString(), nullptr);
790 
791  SwRangeRedline *const pNewRedline(new SwRangeRedline(aData, aRegion));
792  // the point node may be deleted in AppendRedline, so park
793  // the PaM somewhere safe
794  aRegion.DeleteMark();
795  *aRegion.GetPoint() = SwPosition(SwNodeIndex(mrDoc.GetNodes()));
796  mrDoc.getIDocumentRedlineAccess().AppendRedline(pNewRedline, true);
799  }
800  pEntry.reset();
801  }
802 
803  bool CompareRedlines::operator()(const std::unique_ptr<SwFltStackEntry> & pOneE,
804  const std::unique_ptr<SwFltStackEntry> & pTwoE) const
805  {
806  const SwFltRedline *pOne= static_cast<const SwFltRedline*>
807  (pOneE->pAttr.get());
808  const SwFltRedline *pTwo= static_cast<const SwFltRedline*>
809  (pTwoE->pAttr.get());
810 
811  //Return the earlier time, if two have the same time, prioritize
812  //inserts over deletes
813  if (pOne->aStamp == pTwo->aStamp)
814  return (pOne->eType == RedlineType::Insert && pTwo->eType != RedlineType::Insert);
815  else
816  return (pOne->aStamp < pTwo->aStamp);
817  }
818 
820  {
821  std::sort(maStack.begin(), maStack.end(), CompareRedlines());
822  std::for_each(maStack.begin(), maStack.end(), SetInDocAndDelete(mrDoc));
823  }
824 
825  sal_uInt16 WrtRedlineAuthor::AddName( const OUString& rNm )
826  {
827  sal_uInt16 nRet;
828  auto aIter = std::find(maAuthors.begin(), maAuthors.end(), rNm);
829  if (aIter != maAuthors.end())
830  nRet = static_cast< sal_uInt16 >(aIter - maAuthors.begin());
831  else
832  {
833  nRet = static_cast< sal_uInt16 >(maAuthors.size());
834  maAuthors.push_back(rNm);
835  }
836  return nRet;
837  }
838  }
839 
840  namespace util
841  {
843  {
844  rNode.Add(this);
845  }
846 
848  {
849  return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst());
850  }
851 
853  : mbHasRoot(rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
854  {
855  }
856 
858  {
859  if (!mbHasRoot)
860  return;
861  for (auto& aTable : maTables)
862  {
863  // If already a layout exists, then the BoxFrames must recreated at this table
864  SwTableNode *pTable = aTable.first->GetTableNode();
865  OSL_ENSURE(pTable, "Why no expected table");
866  if (pTable)
867  {
868  SwFrameFormat * pFrameFormat = pTable->GetTable().GetFrameFormat();
869 
870  if (pFrameFormat != nullptr)
871  {
872  SwNodeIndex *pIndex = aTable.second;
873  pTable->DelFrames();
874  pTable->MakeOwnFrames(pIndex);
875  }
876  }
877  }
878  }
879 
881  {
882  if (!mbHasRoot)
883  return;
884  //Associate this tablenode with this after position, replace an //old
885  //node association if necessary
886 
887  InsertedTableClient * pClient = new InsertedTableClient(rTableNode);
888 
889  maTables.emplace(pClient, &(rPaM.GetPoint()->nNode));
890  }
891  }
892 
893 }
894 
895 /* 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)
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
SwNodeIndex m_nNode
Definition: fltshell.hxx:50
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:795
virtual Size GetTwipSize() const =0
sal_uIntPtr sal_uLong
#define RES_FLTR_REDLINE
Definition: hintids.hxx:325
bool close(const SwPosition &rPos, RedlineType eType)
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)
SwNode & GetNode() const
Definition: ndindex.hxx:118
bool IsAtEnd() const
long SwTwips
Definition: swtypes.hxx:49
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1552
Dialog to specify the properties of date form field.
Definition: accfrmobj.cxx:38
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:344
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4096
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:40
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:176
#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.
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
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
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:291
css::ui::LayoutSize maLayoutSize
SwDoc * GetDoc()
Definition: node.hxx:702
size_t size() const
Definition: docary.hxx:91
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2813
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:51
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:85
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
SwCharFormat * FindCharFormatByName(const OUString &rName) const
Definition: doc.hxx:767
#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:86
comphelper::EmbeddedObjectContainer & GetEmbeddedObjectContainer() const
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
SwCharFormat * GetCharFormat() const
Definition: fchrfmt.hxx:70
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
#define SAL_WARN_IF(condition, area, stream)
const SwTextFormatColls * GetTextFormatColls() const
Definition: doc.hxx:774
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:2888
std::size_t const nAutorNo
Definition: fltshell.hxx:215
RedlineType const eType
Definition: fltshell.hxx:214
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:4239
ww8::ParaStyles GetParaStyles(const SwDoc &rDoc)
Get the Paragraph Styles of a SwDoc.
SameOpenRedlineType(RedlineType eType)
sal_uInt16 TotalCount() const
SwNodes & GetNodes()
Definition: doc.hxx:402
virtual SwTextFormatColl * GetTextCollFromPool(sal_uInt16 nId, bool bRegardLanguage=true)=0
Return "Auto-Collection with ID.
css::uno::Reference< css::embed::XEmbeddedObject > mxIPRef
WriterSource meWriterType
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:213
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.
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:1308
std::vector< Frame > Frames
STL container of Frames.
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
::basegfx::B2IVector maSize
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1014
Base class of the Writer document model elements.
Definition: node.hxx:79