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 
25 #include <doc.hxx>
26 #include "writerhelper.hxx"
27 #include <msfilter.hxx>
28 #include <com/sun/star/container/XChild.hpp>
29 
30 #include <algorithm>
31 #include <svl/itemiter.hxx>
32 #include <svx/svdobj.hxx>
33 #include <svx/svdoole2.hxx>
35 #include <ndtxt.hxx>
36 #include <ndnotxt.hxx>
37 #include <fmtcntnt.hxx>
38 #include <swtable.hxx>
39 #include <frmfmt.hxx>
40 #include <flypos.hxx>
41 #include <fmtanchr.hxx>
42 #include <fmtfsize.hxx>
43 #include <SwStyleNameMapper.hxx>
44 #include <docary.hxx>
45 #include <charfmt.hxx>
46 #include <fchrfmt.hxx>
47 #include <redline.hxx>
48 #include "types.hxx"
49 #include <svtools/embedhlp.hxx>
50 #include <numrule.hxx>
51 #include <vcl/svapp.hxx>
55 #include <IDocumentMarkAccess.hxx>
56 #include <IMark.hxx>
57 
58 using namespace com::sun::star;
59 
60 namespace
61 {
62  // #i98791# - adjust sorting
63  // Utility to sort SwTextFormatColl's by their assigned outline style list level
64  class outlinecmp
65  {
66  public:
67  bool operator()(const SwTextFormatColl *pA, const SwTextFormatColl *pB) const
68  {
69  // #i98791#
70  bool bResult( false );
71  const bool bIsAAssignedToOutlineStyle( pA->IsAssignedToListLevelOfOutlineStyle() );
72  const bool bIsBAssignedToOutlineStyle( pB->IsAssignedToListLevelOfOutlineStyle() );
73  if ( bIsAAssignedToOutlineStyle != bIsBAssignedToOutlineStyle )
74  {
75  bResult = bIsBAssignedToOutlineStyle;
76  }
77  else if ( !bIsAAssignedToOutlineStyle )
78  {
79  // pA and pB are equal regarding the sorting criteria.
80  // Thus return value does not matter.
81  bResult = false;
82  }
83  else
84  {
86  }
87 
88  return bResult;
89  }
90  };
91 
92  bool IsValidSlotWhich(sal_uInt16 nSlotId, sal_uInt16 nWhichId)
93  {
94  return (nSlotId != 0 && nWhichId != 0 && nSlotId != nWhichId);
95  }
96 
97  /*
98  Utility to convert a SwPosFlyFrames into a simple vector of ww8::Frames
99 
100  The crucial thing is that a ww8::Frame always has an anchor which
101  points to some content in the document. This is a requirement of exporting
102  to Word
103  */
104  ww8::Frames SwPosFlyFramesToFrames(const SwPosFlyFrames &rFlys)
105  {
106  ww8::Frames aRet;
107 
108  for(const auto& rpFly : rFlys)
109  {
110  const SwFrameFormat &rEntry = rpFly->GetFormat();
111 
112  if (const SwPosition* pAnchor = rEntry.GetAnchor().GetContentAnchor())
113  {
114  // the anchor position will be invalidated by SetRedlineFlags
115  // so set a dummy position and fix it in UpdateFramePositions
116  SwPosition const dummy(SwNodeIndex(
117  const_cast<SwNodes&>(pAnchor->nNode.GetNodes())));
118  aRet.emplace_back(rEntry, dummy);
119  }
120  else
121  {
122  SwPosition aPos(rpFly->GetNdIndex());
123 
124  if (SwTextNode* pTextNd = aPos.nNode.GetNode().GetTextNode())
125  {
126  aPos.nContent.Assign(pTextNd, 0);
127  }
128 
129  aRet.emplace_back(rEntry, aPos);
130  }
131  }
132  return aRet;
133  }
134 
135  //Utility to test if a frame is anchored at a given node index
136  class anchoredto
137  {
138  private:
139  sal_uLong mnNode;
140  public:
141  explicit anchoredto(sal_uLong nNode) : mnNode(nNode) {}
142  bool operator()(const ww8::Frame &rFrame) const
143  {
144  return (mnNode == rFrame.GetPosition().nNode.GetNode().GetIndex());
145  }
146  };
147 }
148 
149 namespace ww8
150 {
151  //For i120928,size conversion before exporting graphic of bullet
152  Frame::Frame(const Graphic &rGrf, const SwPosition &rPos)
153  : mpFlyFrame(nullptr)
154  , maPos(rPos)
155  , maSize()
156  , maLayoutSize()
157  , meWriterType(eBulletGrf)
158  , mpStartFrameContent(nullptr)
159  , mbIsInline(true)
160  , mbForBullet(true)
161  , maGrf(rGrf)
162  {
163  const MapMode aMap100mm( MapUnit::Map100thMM );
164  Size aSize( rGrf.GetPrefSize() );
165  if ( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
166  {
167  aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap100mm );
168  }
169  else
170  {
171  aSize = OutputDevice::LogicToLogic( aSize,rGrf.GetPrefMapMode(), aMap100mm );
172  }
173  maSize = aSize;
175  }
176 
177  Frame::Frame(const SwFrameFormat &rFormat, const SwPosition &rPos)
178  : mpFlyFrame(&rFormat)
179  , maPos(rPos)
180  , maSize()
181  , maLayoutSize() // #i43447#
182  , meWriterType(eTextBox)
183  , mpStartFrameContent(nullptr)
184  // #i43447# - move to initialization list
185  , mbIsInline( (rFormat.GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) )
186  // #i120928# - handle graphic of bullet within existing implementation
187  , mbForBullet(false)
188  , maGrf()
189  {
190  switch (rFormat.Which())
191  {
192  case RES_FLYFRMFMT:
193  if (const SwNodeIndex* pIdx = rFormat.GetContent().GetContentIdx())
194  {
195  SwNodeIndex aIdx(*pIdx, 1);
196  const SwNode &rNd = aIdx.GetNode();
197  // #i43447# - determine layout size
198  {
199  SwRect aLayRect( rFormat.FindLayoutRect() );
200  tools::Rectangle aRect( aLayRect.SVRect() );
201  // The Object is not rendered (e.g. something in unused
202  // header/footer) - thus, get the values from the format.
203  if ( aLayRect.IsEmpty() )
204  {
205  aRect.SetSize( rFormat.GetFrameSize().GetSize() );
206  }
207  maLayoutSize = aRect.GetSize();
208  }
209  switch (rNd.GetNodeType())
210  {
211  case SwNodeType::Grf:
213  maSize = rNd.GetNoTextNode()->GetTwipSize();
214  break;
215  case SwNodeType::Ole:
216  meWriterType = eOle;
217  maSize = rNd.GetNoTextNode()->GetTwipSize();
218  break;
219  default:
221  // #i43447# - Size equals layout size for text boxes
223  break;
224  }
225  mpStartFrameContent = &rNd;
226  }
227  else
228  {
229  OSL_ENSURE(false, "Impossible");
231  }
232  break;
233  default:
234  if (const SdrObject* pObj = rFormat.FindRealSdrObject())
235  {
236  if (pObj->GetObjInventor() == SdrInventor::FmForm)
238  else
240  maSize = pObj->GetSnapRect().GetSize();
242  }
243  else
244  {
245  OSL_ENSURE(false, "Impossible");
247  }
248  break;
249  }
250  }
251 
252 
254  {
255  mbIsInline = true;
256  }
257 }
258 
259 namespace sw
260 {
261  namespace hack
262  {
263 
264  sal_uInt16 TransformWhichBetweenPools(const SfxItemPool &rDestPool,
265  const SfxItemPool &rSrcPool, sal_uInt16 nWhich)
266  {
267  sal_uInt16 nSlotId = rSrcPool.GetSlotId(nWhich);
268  if (IsValidSlotWhich(nSlotId, nWhich))
269  nWhich = rDestPool.GetWhich(nSlotId);
270  else
271  nWhich = 0;
272  return nWhich;
273  }
274 
275  sal_uInt16 GetSetWhichFromSwDocWhich(const SfxItemSet &rSet,
276  const SwDoc &rDoc, sal_uInt16 nWhich)
277  {
278  if (RES_WHICHHINT_END < *(rSet.GetRanges()))
279  {
280  nWhich = TransformWhichBetweenPools(*rSet.GetPool(),
281  rDoc.GetAttrPool(), nWhich);
282  }
283  return nWhich;
284  }
285 
287  SfxObjectShell &rPers)
288  : mxIPRef(rObj.GetObjRef()), mrPers(rPers),
289  mpGraphic( rObj.GetGraphic() )
290  {
291  rObj.AbandonObject();
292  }
293 
294  bool DrawingOLEAdaptor::TransferToDoc( OUString &rName )
295  {
296  OSL_ENSURE(mxIPRef.is(), "Transferring invalid object to doc");
297  if (!mxIPRef.is())
298  return false;
299 
300  uno::Reference < container::XChild > xChild( mxIPRef, uno::UNO_QUERY );
301  if ( xChild.is() )
302  xChild->setParent( mrPers.GetModel() );
303 
305  if (bSuccess)
306  {
307  if ( mpGraphic )
310  rName,
311  OUString() );
312 
313  mxIPRef = nullptr;
314  }
315 
316  return bSuccess;
317  }
318 
320  {
321  if (mxIPRef.is())
322  {
323  OSL_ENSURE( !mrPers.GetEmbeddedObjectContainer().HasEmbeddedObject( mxIPRef ), "Object in adaptor is inserted?!" );
324  try
325  {
326  mxIPRef->close(true);
327  }
328  catch ( const css::util::CloseVetoException& )
329  {
330  }
331 
332  mxIPRef = nullptr;
333  }
334  }
335  }
336 
337  namespace util
338  {
340  {
341  if (nIn > SHRT_MAX)
342  nIn = SHRT_MAX;
343  else if (nIn < SHRT_MIN)
344  nIn = SHRT_MIN;
345  return nIn;
346  }
347 
349  {
350  SetObjectLayer(rObject, eHell);
351  }
352 
354  {
355  SetObjectLayer(rObject, eHeaven);
356  }
357 
358  void SetLayer::SetObjectLayer(SdrObject &rObject, Layer eLayer) const
359  {
360  if (SdrInventor::FmForm == rObject.GetObjInventor())
361  rObject.SetLayer(mnFormLayer);
362  else
363  {
364  switch (eLayer)
365  {
366  case eHeaven:
367  rObject.SetLayer(mnHeavenLayer);
368  break;
369  case eHell:
370  rObject.SetLayer(mnHellLayer);
371  break;
372  }
373  }
374  }
375 
376  //SetLayer boilerplate begin
377 
378  // #i38889# - by default put objects into the invisible layers.
380  : mnHeavenLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleHeavenId()),
381  mnHellLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleHellId()),
382  mnFormLayer(rDoc.getIDocumentDrawModelAccess().GetInvisibleControlsId())
383  {
384  }
385  //SetLayer boilerplate end
386 
387  void GetPoolItems(const SfxItemSet &rSet, ww8::PoolItems &rItems, bool bExportParentItemSet )
388  {
389  if( bExportParentItemSet )
390  {
391  sal_uInt16 nTotal = rSet.TotalCount();
392  for( sal_uInt16 nItem =0; nItem < nTotal; ++nItem )
393  {
394  const SfxPoolItem* pItem = nullptr;
395  if( SfxItemState::SET == rSet.GetItemState( rSet.GetWhichByPos( nItem ), true, &pItem ) )
396  {
397  rItems[pItem->Which()] = pItem;
398  }
399  }
400  }
401  else if( rSet.Count())
402  {
403  SfxItemIter aIter(rSet);
404  if (const SfxPoolItem *pItem = aIter.GetCurItem())
405  {
406  do
407  rItems[pItem->Which()] = pItem;
408  while ((pItem = aIter.NextItem()));
409  }
410  }
411  }
412 
414  sal_uInt16 eType)
415  {
416  auto aIter = rItems.find(eType);
417  if (aIter != rItems.end())
418  return aIter->second;
419  return nullptr;
420  }
421 
423  {
424  if (const SwCharFormat* pCharFormat = rFormat.GetCharFormat())
425  {
426  if (pCharFormat->GetAttrSet().Count())
427  {
428  SfxItemIter aIter(pCharFormat->GetAttrSet());
429  const SfxPoolItem *pItem = aIter.GetCurItem();
430  do
431  rSet.ClearItem(pItem->Which());
432  while ((pItem = aIter.NextItem()));
433  }
434  }
435  }
436 
438  {
439  ww8::ParaStyles aStyles;
440  typedef ww8::ParaStyles::size_type mysizet;
441 
442  const SwTextFormatColls *pColls = rDoc.GetTextFormatColls();
443  mysizet nCount = pColls ? pColls->size() : 0;
444  aStyles.reserve(nCount);
445  for (mysizet nI = 0; nI < nCount; ++nI)
446  aStyles.push_back((*pColls)[ static_cast< sal_uInt16 >(nI) ]);
447  return aStyles;
448  }
449 
450  SwTextFormatColl* GetParaStyle(SwDoc &rDoc, const OUString& rName)
451  {
452  // Search first in the Doc-Styles
453  SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName(rName);
454  if (!pColl)
455  {
456  // Collection not found, try in Pool ?
457  sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
459  if (n != SAL_MAX_UINT16) // found or standard
460  pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool(n, false);
461  }
462  return pColl;
463  }
464 
465  SwCharFormat* GetCharStyle(SwDoc &rDoc, const OUString& rName)
466  {
467  SwCharFormat *pFormat = rDoc.FindCharFormatByName(rName);
468  if (!pFormat)
469  {
470  // Collection not found, try in Pool ?
471  sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(rName,
473  if (n != SAL_MAX_UINT16) // found or standard
475  }
476  return pFormat;
477  }
478 
479  // #i98791# - adjust sorting algorithm
481  {
482  std::sort(rStyles.begin(), rStyles.end(), outlinecmp());
483  }
484 
485  /*
486  Utility to extract FlyFormats from a document, potentially from a
487  selection.
488  */
489  ww8::Frames GetFrames(const SwDoc &rDoc, SwPaM const *pPaM /*, bool bAll*/)
490  {
491  SwPosFlyFrames aFlys(rDoc.GetAllFlyFormats(pPaM, true));
492  ww8::Frames aRet(SwPosFlyFramesToFrames(aFlys));
493  return aRet;
494  }
495 
497  {
498  for (ww8::Frame & rFrame : rFrames)
499  {
500  SwFormatAnchor const& rAnchor = rFrame.GetFrameFormat().GetAnchor();
501  if (SwPosition const*const pAnchor = rAnchor.GetContentAnchor())
502  {
503  rFrame.SetPosition(*pAnchor);
504  }
505  else
506  { // these don't need to be corrected, they're not in redlines
507  assert(RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId());
508  }
509  }
510  }
511 
512  ww8::Frames GetFramesInNode(const ww8::Frames &rFrames, const SwNode &rNode)
513  {
514  ww8::Frames aRet;
515  std::copy_if(rFrames.begin(), rFrames.end(),
516  std::back_inserter(aRet), anchoredto(rNode.GetIndex()));
517  return aRet;
518  }
519 
521  int nLevel)
522  {
523  if (nLevel < 0 || nLevel >= MAXLEVEL)
524  {
525  OSL_FAIL("Invalid level");
526  return nullptr;
527  }
528  return &(rRule.Get( static_cast< sal_uInt16 >(nLevel) ));
529  }
530 
532  {
533  const SwNumRule *pRule = nullptr;
534  if (
535  rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
536  nullptr != (pRule = rTextNode.GetNumRule())
537  )
538  {
539  return GetNumFormatFromSwNumRuleLevel(*pRule,
540  rTextNode.GetActualListLevel());
541  }
542 
543  OSL_ENSURE(rTextNode.GetDoc(), "No document for node?, suspicious");
544  if (!rTextNode.GetDoc())
545  return nullptr;
546 
547  if (
548  rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
549  nullptr != (pRule = rTextNode.GetDoc()->GetOutlineNumRule())
550  )
551  {
552  return GetNumFormatFromSwNumRuleLevel(*pRule,
553  rTextNode.GetActualListLevel());
554  }
555 
556  return nullptr;
557  }
558 
559  const SwNumRule* GetNumRuleFromTextNode(const SwTextNode &rTextNode)
560  {
561  return GetNormalNumRuleFromTextNode(rTextNode);
562  }
563 
565  {
566  const SwNumRule *pRule = nullptr;
567 
568  if (
569  rTextNode.IsNumbered() && rTextNode.IsCountedInList() &&
570  nullptr != (pRule = rTextNode.GetNumRule())
571  )
572  {
573  return pRule;
574  }
575  return nullptr;
576  }
577 
579  {
580  const SwNodeIndex *pIndex = rFormat.GetContent().GetContentIdx();
581  OSL_ENSURE(pIndex, "No NodeIndex in SwFrameFormat ?, suspicious");
582  if (!pIndex)
583  return nullptr;
584  SwNodeIndex aIdx(*pIndex, 1);
585  return aIdx.GetNode().GetNoTextNode();
586  }
587 
588  bool HasPageBreak(const SwNode &rNd)
589  {
590  const SvxFormatBreakItem *pBreak = nullptr;
591  if (rNd.IsTableNode() && rNd.GetTableNode())
592  {
593  const SwTable& rTable = rNd.GetTableNode()->GetTable();
594  const SwFrameFormat* pApply = rTable.GetFrameFormat();
595  OSL_ENSURE(pApply, "impossible");
596  if (pApply)
597  pBreak = &(ItemGet<SvxFormatBreakItem>(*pApply, RES_BREAK));
598  }
599  else if (const SwContentNode *pNd = rNd.GetContentNode())
600  pBreak = &(ItemGet<SvxFormatBreakItem>(*pNd, RES_BREAK));
601 
602  return pBreak && pBreak->GetBreak() == SvxBreak::PageBefore;
603  }
604 
606  {
607  if(1 == rPolyPoly.Count())
608  {
609  return rPolyPoly[0];
610  }
611  else
612  {
613  // This method will now just concatenate the polygons contained
614  // in the given PolyPolygon. Anything else which might be thought of
615  // for reducing to a single polygon will just need more power and
616  // cannot create more correct results.
617  sal_uInt32 nPointCount(0);
618  sal_uInt16 a;
619 
620  for(a = 0; a < rPolyPoly.Count(); a++)
621  {
622  nPointCount += static_cast<sal_uInt32>(rPolyPoly[a].GetSize());
623  }
624 
625  if(nPointCount > 0x0000ffff)
626  {
627  OSL_FAIL("PolygonFromPolyPolygon: too many points for a single polygon (!)");
628  nPointCount = 0x0000ffff;
629  }
630 
631  tools::Polygon aRetval(static_cast<sal_uInt16>(nPointCount));
632  sal_uInt32 nAppendIndex(0);
633 
634  for(a = 0; a < rPolyPoly.Count(); a++)
635  {
636  const tools::Polygon& rCandidate = rPolyPoly[a];
637 
638  for(sal_uInt16 b(0); nAppendIndex <= nPointCount && b < rCandidate.GetSize(); b++)
639  {
640  aRetval[static_cast<sal_uInt16>(nAppendIndex++)] = rCandidate[b];
641  }
642  }
643 
644  return aRetval;
645  }
646  }
647 
649  {
650  tools::Polygon aPoly(PolygonFromPolyPolygon(rPolyPoly));
651  const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
652  Fraction aMapPolyX(ww::nWrap100Percent, rOrigSize.Width());
653  Fraction aMapPolyY(ww::nWrap100Percent, rOrigSize.Height());
654  aPoly.Scale(double(aMapPolyX), double(aMapPolyY));
655 
656  /*
657  a) stretch right bound by 15twips
658  b) shrink bottom bound to where it would have been in word
659  c) Move it to the left by 15twips
660 
661  See the import for details
662  */
663  const Size &rSize = pNd->GetTwipSize();
664  Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
665  aMoveHack *= Fraction(15, 1);
666  long nMove(aMoveHack);
667 
668  Fraction aHackX(ww::nWrap100Percent + nMove,
670  Fraction aHackY(ww::nWrap100Percent - nMove,
672  aPoly.Scale(double(aHackX), double(aHackY));
673 
674  aPoly.Move(-nMove, 0);
675  return aPoly;
676  }
677 
678  void RedlineStack::open(const SwPosition& rPos, const SfxPoolItem& rAttr)
679  {
680  OSL_ENSURE(rAttr.Which() == RES_FLTR_REDLINE, "not a redline");
681  maStack.emplace_back(new SwFltStackEntry(rPos, std::unique_ptr<SfxPoolItem>(rAttr.Clone())));
682  }
683 
684  namespace {
685 
686  class SameOpenRedlineType
687  {
688  private:
690  public:
691  explicit SameOpenRedlineType(RedlineType eType) : meType(eType) {}
692  bool operator()(const std::unique_ptr<SwFltStackEntry> & pEntry) const
693  {
694  const SwFltRedline *pTest = static_cast<const SwFltRedline *>
695  (pEntry->pAttr.get());
696  return (pEntry->bOpen && (pTest->eType == meType));
697  }
698  };
699 
700  }
701 
702  bool RedlineStack::close(const SwPosition& rPos, RedlineType eType)
703  {
704  //Search from end for same type
705  auto aResult = std::find_if(maStack.rbegin(), maStack.rend(),
706  SameOpenRedlineType(eType));
707  if (aResult != maStack.rend())
708  {
709  SwTextNode *const pNode(rPos.nNode.GetNode().GetTextNode());
710  sal_Int32 const nIndex(rPos.nContent.GetIndex());
711  // HACK to prevent overlap of field-mark and redline,
712  // which would destroy field-mark invariants when the redline
713  // is hidden: move the redline end one to the left
714  if (pNode && nIndex > 0
715  && pNode->GetText()[nIndex - 1] == CH_TXT_ATR_FIELDEND)
716  {
717  SwPosition const end(*rPos.nNode.GetNode().GetTextNode(),
718  nIndex - 1);
719  sw::mark::IFieldmark *const pFieldMark(
721  SAL_WARN_IF(!pFieldMark, "sw.ww8", "expected a field mark");
722  if (pFieldMark && pFieldMark->GetMarkPos().nNode.GetIndex() == (*aResult)->m_aMkPos.m_nNode.GetIndex()+1
723  && pFieldMark->GetMarkPos().nContent.GetIndex() < (*aResult)->m_aMkPos.m_nContent)
724  {
725  (*aResult)->SetEndPos(end);
726  return true;
727  }
728  }
729  (*aResult)->SetEndPos(rPos);
730  return true;
731  }
732  return false;
733  }
734 
736  {
737  std::for_each(maStack.begin(), maStack.end(), SetEndIfOpen(rPos));
738  }
739 
741  {
742  size_t nCnt = maStack.size();
743  sal_Int32 const nInserted = 2; // CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDSEP
744  sal_uLong nPosNd = rPos.nNode.GetIndex();
745  sal_Int32 nPosCt = rPos.nContent.GetIndex() - nInserted;
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 += nInserted;
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 += nInserted;
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 += nInserted;
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 (pEntry->MakeRegion(&mrDoc, aRegion,
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  : m_pTableNode(&rNode)
844  {
845  StartListening(rNode.GetNotifier());
846  }
847 
849  { return m_pTableNode; }
850 
852  {
853  if(rHint.GetId() == SfxHintId::Dying)
854  m_pTableNode = nullptr;
855  }
856 
858  : mbHasRoot(rDoc.getIDocumentLayoutAccess().GetCurrentLayout())
859  { }
860 
862  {
863  if (!mbHasRoot)
864  return;
865  for (auto& aTable : maTables)
866  {
867  // If already a layout exists, then the BoxFrames must recreated at this table
868  SwTableNode *pTable = aTable.first->GetTableNode();
869  OSL_ENSURE(pTable, "Why no expected table");
870  if (pTable)
871  {
872  SwFrameFormat * pFrameFormat = pTable->GetTable().GetFrameFormat();
873 
874  if (pFrameFormat != nullptr)
875  {
876  SwNodeIndex *pIndex = aTable.second;
877  pTable->DelFrames();
878  pTable->MakeOwnFrames(pIndex);
879  }
880  }
881  }
882  }
883 
885  {
886  if (!mbHasRoot)
887  return;
888  //Associate this tablenode with this after position, replace an //old
889  //node association if necessary
890  maTables.emplace(
891  std::unique_ptr<InsertedTableListener>(new InsertedTableListener(rTableNode)),
892  &(rPaM.GetPoint()->nNode));
893  }
894  }
895 
896 }
897 
898 /* 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:228
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.
sal_Int32 nIndex
int GetAssignedOutlineStyleLevel() const
Definition: fmtcol.cxx:587
InsertedTablesManager(const SwDoc &rDoc)
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
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
const char aData[]
Definition: ww8scan.hxx:47
void closeall(const SwPosition &rPos)
Frame(const SwFrameFormat &rFlyFrame, const SwPosition &rPos)
constexpr sal_uInt16 RES_WHICHHINT_END(HINT_END)
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
SwNodeIndex m_nNode
Definition: fltshell.hxx:51
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:798
virtual Size GetTwipSize() const =0
sal_uIntPtr sal_uLong
bool close(const SwPosition &rPos, RedlineType eType)
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2648
const SwPosition * GetMark() const
Definition: pam.hxx:209
sal_Int64 n
Definition: doc.hxx:186
bool HasEmbeddedObject(const OUString &)
constexpr TypedWhichId< SvxFormatBreakItem > RES_BREAK(94)
sal_uInt16 AddName(const OUString &rNm)
SwNode & GetNode() const
Definition: ndindex.hxx:119
long SwTwips
Definition: swtypes.hxx:49
void MoveAttrsFieldmarkInserted(const SwPosition &rPos)
IDocumentMarkAccess * getIDocumentMarkAccess()
Definition: docbm.cxx:1683
Dialog to specify the properties of date form field.
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:35
std::vector< OUString > maAuthors
Definition: msfilter.hxx:347
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4089
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:201
SfxHintId GetId() const
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:502
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()
const SfxPoolItem * NextItem()
bool IsAssignedToListLevelOfOutlineStyle() const
Definition: fmtcol.hxx:109
RedlineType eType
Definition: fltshell.hxx:216
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.
IDocumentStylePoolAccess const & getIDocumentStylePoolAccess() const
Definition: doc.cxx:425
void open(const SwPosition &rPos, const SfxPoolItem &rAttr)
int nCount
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
static SW_DLLPUBLIC sal_uInt16 GetPoolIdFromUIName(const OUString &rName, SwGetPoolIdFromName)
void InsertTable(SwTableNode &rTableNode, SwPaM &rPaM)
constexpr TypedWhichId< SwFltRedline > RES_FLTR_REDLINE(192)
const SwTable & GetTable() const
Definition: node.hxx:497
const SwNumRule * GetNumRuleFromTextNode(const SwTextNode &rTextNode)
RedlineFlags on.
const SwFrameFormat & GetFrameFormat() const
Get the writer SwFrameFormat that this object describes.
void SendObjectToHeaven(SdrObject &rObject) const
Make Object lives in the top layer.
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
int i
uno_Any a
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:206
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)
SwContentNode * GetContentNode()
Definition: node.hxx:615
FlyAnchors.
Definition: fmtanchr.hxx:34
sal_uInt16 Count() const
SwNoTextNode * GetNoTextNode()
Definition: ndnotxt.hxx:96
std::vector< std::unique_ptr< SwFltStackEntry > > maStack
Definition: msfilter.hxx:294
css::ui::LayoutSize maLayoutSize
SwDoc * GetDoc()
Definition: node.hxx:702
size_t size() const
Definition: docary.hxx:84
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2805
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
sal_uInt16 GetWhichByPos(sal_uInt16 nPos) const
sal_Int32 m_nContent
Definition: fltshell.hxx:52
bool StartListening(SvtBroadcaster &rBroadcaster)
std::size_t nAutorNo
Definition: fltshell.hxx:217
InsertedTableListener(SwTableNode &rNode)
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:86
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.
SvtBroadcaster & GetNotifier()
Definition: calbck.hxx:93
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:78
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:78
SwCharFormat * FindCharFormatByName(const OUString &rName) const
Definition: doc.hxx:770
Size maLayoutSize
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
SwFltPosition m_aPtPos
Definition: fltshell.hxx:87
comphelper::EmbeddedObjectContainer & GetEmbeddedObjectContainer() const
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:334
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:777
MapMode GetPrefMapMode() const
const SwNodes & GetNodes() const
Definition: ndindex.hxx:156
Make exporting a Writer Frame easy.
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2880
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:4232
ww8::ParaStyles GetParaStyles(const SwDoc &rDoc)
Get the Paragraph Styles of a SwDoc.
sal_uInt16 TotalCount() const
SwNodes & GetNodes()
Definition: doc.hxx:405
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()
virtual void Notify(const SfxHint &) override
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:181
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(154)
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
RndStdIds
bool IsTableNode() const
Definition: node.hxx:640
void SendObjectToHell(SdrObject &rObject) const
Make Object live in the bottom drawing layer.
DateTime aStamp
Definition: fltshell.hxx:215
RedlineType
SdrLayerID mnHeavenLayer
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.
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.
RedlineType meType
sal_uInt16 Which() const
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2701
no RedlineFlags
const Size & GetSize() const
const SfxPoolItem * GetCurItem() const
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1317
std::vector< Frame > Frames
STL container of Frames.
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:836
::basegfx::B2IVector maSize
SwNumRule * GetOutlineNumRule() const
Definition: doc.hxx:1023
Base class of the Writer document model elements.
Definition: node.hxx:79