LibreOffice Module sw (master)  1
textboxhelper.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 
10 #include <textboxhelper.hxx>
11 #include <fmtcntnt.hxx>
12 #include <fmtanchr.hxx>
13 #include <fmtcnct.hxx>
14 #include <fmtornt.hxx>
15 #include <fmtfsize.hxx>
16 #include <doc.hxx>
18 #include <IDocumentState.hxx>
19 #include <docsh.hxx>
20 #include <unocoll.hxx>
21 #include <unoframe.hxx>
22 #include <unodraw.hxx>
23 #include <unotextrange.hxx>
24 #include <cmdid.h>
25 #include <unomid.h>
26 #include <unoprnms.hxx>
27 #include <mvsave.hxx>
28 #include <fmtsrnd.hxx>
29 #include <frmfmt.hxx>
30 #include <frameformats.hxx>
31 #include <dflyobj.hxx>
32 
33 #include <editeng/unoprnms.hxx>
34 #include <editeng/memberids.h>
35 #include <svx/svdoashp.hxx>
36 #include <svx/svdpage.hxx>
37 #include <svx/svdogrp.hxx>
38 #include <svl/itemiter.hxx>
40 #include <sal/log.hxx>
41 #include <tools/UnitConversion.hxx>
42 #include <svx/swframetypes.hxx>
43 #include <drawdoc.hxx>
44 #include <IDocumentUndoRedo.hxx>
46 #include <frmatr.hxx>
47 
48 #include <com/sun/star/document/XActionLockable.hpp>
49 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
50 #include <com/sun/star/text/SizeType.hpp>
51 #include <com/sun/star/text/WrapTextMode.hpp>
52 #include <com/sun/star/text/XTextDocument.hpp>
53 #include <com/sun/star/text/XTextFrame.hpp>
54 #include <com/sun/star/table/BorderLine2.hpp>
55 #include <com/sun/star/text/WritingMode.hpp>
56 #include <com/sun/star/text/WritingMode2.hpp>
57 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
58 #include <com/sun/star/style/ParagraphAdjust.hpp>
59 
60 using namespace com::sun::star;
61 
62 void SwTextBoxHelper::create(SwFrameFormat* pShape, SdrObject* pObject, bool bCopyText)
63 {
64  assert(pShape);
65  assert(pObject);
66 
67  const bool bIsGroupObj = dynamic_cast<SdrObjGroup*>(pObject->getParentSdrObjectFromSdrObject());
68 
69  // If TextBox wasn't enabled previously
70  if (pShape->GetOtherTextBoxFormat() && pShape->GetOtherTextBoxFormat()->GetTextBox(pObject))
71  return;
72 
73  // Store the current text content of the shape
74  OUString sCopyableText;
75 
76  if (bCopyText)
77  {
78  if (pObject)
79  {
80  uno::Reference<text::XText> xSrcCnt(pObject->getWeakUnoShape(), uno::UNO_QUERY);
81  auto xCur = xSrcCnt->createTextCursor();
82  xCur->gotoStart(false);
83  xCur->gotoEnd(true);
84  sCopyableText = xCur->getText()->getString();
85  }
86  }
87 
88  // Create the associated TextFrame and insert it into the document.
89  uno::Reference<text::XTextContent> xTextFrame(
91  uno::UNO_QUERY);
92  uno::Reference<text::XTextDocument> xTextDocument(
93  pShape->GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
94  uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(),
95  uno::UNO_QUERY);
96  try
97  {
98  uno::Reference<text::XTextContent> XSourceShape(pObject->getUnoShape(),
99  uno::UNO_QUERY_THROW);
100  xTextContentAppend->insertTextContentWithProperties(
101  xTextFrame, uno::Sequence<beans::PropertyValue>(), XSourceShape->getAnchor());
102  }
103  catch (uno::Exception&)
104  {
105  xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>());
106  }
107  // Link FLY and DRAW formats, so it becomes a text box (needed for syncProperty calls).
108  uno::Reference<text::XTextFrame> xRealTextFrame(xTextFrame, uno::UNO_QUERY);
109  auto pTextFrame = dynamic_cast<SwXTextFrame*>(xRealTextFrame.get());
110  assert(nullptr != pTextFrame);
111  SwFrameFormat* pFormat = pTextFrame->GetFrameFormat();
112 
113  assert(nullptr != dynamic_cast<SwDrawFrameFormat*>(pShape));
114  assert(nullptr != dynamic_cast<SwFlyFrameFormat*>(pFormat));
115 
116  if (!pShape->GetOtherTextBoxFormat())
117  {
118  auto* pTextBox = new SwTextBoxNode(pShape);
119  pTextBox->AddTextBox(pObject, pFormat);
120  pShape->SetOtherTextBoxFormat(pTextBox);
121  pFormat->SetOtherTextBoxFormat(pTextBox);
122  }
123  else
124  {
125  auto* pTextBox = pShape->GetOtherTextBoxFormat();
126  pTextBox->AddTextBox(pObject, pFormat);
127  pShape->SetOtherTextBoxFormat(pTextBox);
128  pFormat->SetOtherTextBoxFormat(pTextBox);
129  }
130  // Initialize properties.
131  uno::Reference<beans::XPropertySet> xPropertySet(xTextFrame, uno::UNO_QUERY);
132  uno::Any aEmptyBorder = uno::makeAny(table::BorderLine2());
133  xPropertySet->setPropertyValue(UNO_NAME_TOP_BORDER, aEmptyBorder);
134  xPropertySet->setPropertyValue(UNO_NAME_BOTTOM_BORDER, aEmptyBorder);
135  xPropertySet->setPropertyValue(UNO_NAME_LEFT_BORDER, aEmptyBorder);
136  xPropertySet->setPropertyValue(UNO_NAME_RIGHT_BORDER, aEmptyBorder);
137 
138  xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::makeAny(sal_Int32(100)));
139 
140  xPropertySet->setPropertyValue(UNO_NAME_SIZE_TYPE, uno::makeAny(text::SizeType::FIX));
141 
142  xPropertySet->setPropertyValue(UNO_NAME_SURROUND, uno::makeAny(text::WrapTextMode_THROUGH));
143 
144  uno::Reference<container::XNamed> xNamed(xTextFrame, uno::UNO_QUERY);
145  xNamed->setName(pShape->GetDoc()->GetUniqueFrameName());
146 
147  // Link its text range to the original shape.
148  uno::Reference<text::XTextRange> xTextBox(xTextFrame, uno::UNO_QUERY_THROW);
149  SwUnoInternalPaM aInternalPaM(*pShape->GetDoc());
150  if (sw::XTextRangeToSwPaM(aInternalPaM, xTextBox))
151  {
152  SwAttrSet aSet(pShape->GetAttrSet());
153  SwFormatContent aContent(aInternalPaM.GetNode().StartOfSectionNode());
154  aSet.Put(aContent);
155  pShape->SetFormatAttr(aSet);
156  }
157 
158  DoTextBoxZOrderCorrection(pShape, pObject);
159 
160  // Also initialize the properties, which are not constant, but inherited from the shape's ones.
161  uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
162  syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::makeAny(xShape->getSize()), pObject);
163 
164  uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
165  syncProperty(pShape, RES_FOLLOW_TEXT_FLOW, MID_FOLLOW_TEXT_FLOW,
166  xShapePropertySet->getPropertyValue(UNO_NAME_IS_FOLLOWING_TEXT_FLOW), pObject);
167  syncProperty(pShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE,
168  xShapePropertySet->getPropertyValue(UNO_NAME_ANCHOR_TYPE), pObject);
169  syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_ORIENT,
170  xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT), pObject);
171  syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_RELATION,
172  xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_RELATION), pObject);
173  syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_ORIENT,
174  xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT), pObject);
175  syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_RELATION,
176  xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_RELATION), pObject);
177  syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_POSITION,
178  xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_POSITION), pObject);
179  syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_POSITION,
180  xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_POSITION), pObject);
181  syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT,
182  xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT), pObject);
183  syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0,
184  xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_VERT_ADJUST), pObject);
185  text::WritingMode eMode;
186  if (xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_WRITINGMODE) >>= eMode)
187  syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)), pObject);
188 
189  if (bIsGroupObj)
190  doTextBoxPositioning(pShape, pObject);
191 
192  // Check if the shape had text before and move it to the new textframe
193  if (!bCopyText || sCopyableText.isEmpty())
194  return;
195 
196  if (pObject)
197  {
198  auto pSourceText = dynamic_cast<SdrTextObj*>(pObject);
199  uno::Reference<text::XTextRange> xDestText(xRealTextFrame, uno::UNO_QUERY);
200 
201  xDestText->setString(sCopyableText);
202 
203  if (pSourceText)
204  pSourceText->SetText(OUString());
205 
206  pShape->GetDoc()->getIDocumentState().SetModified();
207  }
208 }
209 
210 void SwTextBoxHelper::destroy(const SwFrameFormat* pShape, const SdrObject* pObject)
211 {
212  // If a TextBox was enabled previously
213  auto pTextBox = pShape->GetOtherTextBoxFormat();
214  if (pTextBox && pTextBox->IsTextBoxActive(pObject))
215  {
216  // Unlink the TextBox's text range from the original shape.
217  pTextBox->SetTextBoxInactive(pObject);
218 
219  // Delete the associated TextFrame.
220  pTextBox->DelTextBox(pObject);
221  }
222 }
223 
224 bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pFormat, sal_uInt16 nType,
225  const SdrObject* pObject)
226 {
227  SolarMutexGuard aGuard;
228  assert(nType == RES_FLYFRMFMT || nType == RES_DRAWFRMFMT);
229  if (!pFormat || pFormat->Which() != nType)
230  return false;
231 
232  auto pTextBox = pFormat->GetOtherTextBoxFormat();
233  if (!pTextBox)
234  return false;
235 
236  if (nType == RES_DRAWFRMFMT)
237  {
238  if (pObject)
239  return pTextBox->GetTextBox(pObject);
240  if (auto pObj = pFormat->FindRealSdrObject())
241  return pTextBox->GetTextBox(pObj);
242  }
243 
244  if (nType == RES_FLYFRMFMT)
245  {
246  return pTextBox->GetOwnerShape();
247  }
248 
249  return false;
250 }
251 
253 {
254  if (!pObj)
255  return false;
256 
257  uno::Reference<drawing::XShape> xShape(pObj->getWeakUnoShape(), uno::UNO_QUERY);
258  if (!xShape)
259  return false;
261 }
262 
263 sal_Int32 SwTextBoxHelper::getCount(SdrPage const* pPage)
264 {
265  sal_Int32 nRet = 0;
266  for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
267  {
268  SdrObject* p = pPage->GetObj(i);
269  if (p && p->IsTextBox())
270  continue;
271  ++nRet;
272  }
273  return nRet;
274 }
275 
276 sal_Int32 SwTextBoxHelper::getCount(const SwDoc& rDoc)
277 {
278  sal_Int32 nRet = 0;
279  const SwFrameFormats& rSpzFrameFormats = *rDoc.GetSpzFrameFormats();
280  for (const auto pFormat : rSpzFrameFormats)
281  {
282  if (isTextBox(pFormat, RES_FLYFRMFMT))
283  ++nRet;
284  }
285  return nRet;
286 }
287 
288 uno::Any SwTextBoxHelper::getByIndex(SdrPage const* pPage, sal_Int32 nIndex)
289 {
290  if (nIndex < 0)
291  throw lang::IndexOutOfBoundsException();
292 
293  SdrObject* pRet = nullptr;
294  sal_Int32 nCount = 0; // Current logical index.
295  for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
296  {
297  SdrObject* p = pPage->GetObj(i);
298  if (p && p->IsTextBox())
299  continue;
300  if (nCount == nIndex)
301  {
302  pRet = p;
303  break;
304  }
305  ++nCount;
306  }
307 
308  if (!pRet)
309  throw lang::IndexOutOfBoundsException();
310 
311  return uno::makeAny(uno::Reference<drawing::XShape>(pRet->getUnoShape(), uno::UNO_QUERY));
312 }
313 
314 sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject)
315 {
316  if (const SdrPage* pPage = pObject->getSdrPageFromSdrObject())
317  {
318  sal_Int32 nOrder = 0; // Current logical order.
319  for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
320  {
321  SdrObject* p = pPage->GetObj(i);
322  if (p && p->IsTextBox())
323  continue;
324  if (p == pObject)
325  return nOrder;
326  ++nOrder;
327  }
328  }
329 
330  SAL_WARN("sw.core", "SwTextBoxHelper::getOrdNum: no page or page doesn't contain the object");
331  return pObject->GetOrdNum();
332 }
333 
334 void SwTextBoxHelper::getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& rWrapThrough)
335 {
337  if (pShape)
338  rWrapThrough = pShape->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH;
339 }
340 
342  sal_uInt16 nType, const SdrObject* pObject)
343 {
344  SolarMutexGuard aGuard;
345  if (!isTextBox(pFormat, nType, pObject))
346  return nullptr;
347 
348  if (nType == RES_DRAWFRMFMT)
349  {
350  if (pObject)
351  return pFormat->GetOtherTextBoxFormat()->GetTextBox(pObject);
352  if (pFormat->FindRealSdrObject())
353  return pFormat->GetOtherTextBoxFormat()->GetTextBox(pFormat->FindRealSdrObject());
354  return nullptr;
355  }
356  if (nType == RES_FLYFRMFMT)
357  {
358  return pFormat->GetOtherTextBoxFormat()->GetOwnerShape();
359  }
360  return nullptr;
361 }
362 
363 SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XShape> const& xShape)
364 {
365  auto pShape = dynamic_cast<SwXShape*>(xShape.get());
366  if (!pShape)
367  return nullptr;
368 
369  SwFrameFormat* pFormat = pShape->GetFrameFormat();
370  return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT);
371 }
372 
373 uno::Reference<text::XTextFrame>
374 SwTextBoxHelper::getUnoTextFrame(uno::Reference<drawing::XShape> const& xShape)
375 {
376  if (xShape)
377  {
378  auto pFrameFormat = SwTextBoxHelper::getOtherTextBoxFormat(xShape);
379  if (pFrameFormat)
380  {
381  auto pSdrObj = pFrameFormat->FindSdrObject();
382  if (pSdrObj)
383  {
384  return { pSdrObj->getUnoShape(), uno::UNO_QUERY };
385  }
386  }
387  }
388  return {};
389 }
390 
391 template <typename T> static void lcl_queryInterface(const SwFrameFormat* pShape, uno::Any& rAny)
392 {
394  {
395  uno::Reference<T> const xInterface(
396  SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
397  rAny <<= xInterface;
398  }
399 }
400 
402 {
403  uno::Any aRet;
404 
406  {
407  lcl_queryInterface<text::XTextAppend>(pShape, aRet);
408  }
409  else if (rType == cppu::UnoType<css::text::XText>::get())
410  {
411  lcl_queryInterface<text::XText>(pShape, aRet);
412  }
413  else if (rType == cppu::UnoType<css::text::XTextRange>::get())
414  {
415  lcl_queryInterface<text::XTextRange>(pShape, aRet);
416  }
417 
418  return aRet;
419 }
420 
422 {
423  tools::Rectangle aRet;
424  aRet.SetEmpty();
425 
426  assert(pShape);
427 
428  auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(pShape);
429  if (pCustomShape)
430  {
431  // Need to temporarily release the lock acquired in
432  // SdXMLShapeContext::AddShape(), otherwise we get an empty rectangle,
433  // see EnhancedCustomShapeEngine::getTextBounds().
434  uno::Reference<document::XActionLockable> xLockable(pCustomShape->getUnoShape(),
435  uno::UNO_QUERY);
436  sal_Int16 nLocks = 0;
437  if (xLockable.is())
438  nLocks = xLockable->resetActionLocks();
439  pCustomShape->GetTextBounds(aRet);
440  if (nLocks)
441  xLockable->setActionLocks(nLocks);
442  }
443  else if (pShape)
444  {
445  // fallback - get *any* bound rect we can possibly get hold of
446  aRet = pShape->GetCurrentBoundRect();
447  }
448 
449  if (!bAbsolute && pShape)
450  {
451  // Relative, so count the logic (reference) rectangle, see the EnhancedCustomShape2d ctor.
452  Point aPoint(pShape->GetSnapRect().Center());
453  Size aSize(pShape->GetLogicRect().GetSize());
454  aPoint.AdjustX(-(aSize.Width() / 2));
455  aPoint.AdjustY(-(aSize.Height() / 2));
456  tools::Rectangle aLogicRect(aPoint, aSize);
457  aRet.Move(-1 * aLogicRect.Left(), -1 * aLogicRect.Top());
458  }
459 
460  return aRet;
461 }
462 
463 void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, std::u16string_view rPropertyName,
464  const css::uno::Any& rValue, SdrObject* pObj)
465 {
466  // Textframes does not have valid horizontal adjust property, so map it to paragraph adjust property
467  if (rPropertyName == UNO_NAME_TEXT_HORZADJUST)
468  {
469  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
470  if (!pFormat)
471  return;
472 
473  auto xTextFrame = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
474  uno::Reference<text::XTextCursor> xCursor = xTextFrame->getText()->createTextCursor();
475 
476  // Select all paragraphs in the textframe
477  xCursor->gotoStart(false);
478  xCursor->gotoEnd(true);
479  uno::Reference<beans::XPropertySet> xFrameParaProps(xCursor, uno::UNO_QUERY);
480 
481  // And simply map the property
482  const auto eValue = rValue.get<drawing::TextHorizontalAdjust>();
483  switch (eValue)
484  {
485  case drawing::TextHorizontalAdjust::TextHorizontalAdjust_CENTER:
486  xFrameParaProps->setPropertyValue(
488  uno::makeAny(style::ParagraphAdjust::ParagraphAdjust_CENTER)); //3
489  break;
490  case drawing::TextHorizontalAdjust::TextHorizontalAdjust_LEFT:
491  xFrameParaProps->setPropertyValue(
493  uno::makeAny(style::ParagraphAdjust::ParagraphAdjust_LEFT)); //0
494  break;
495  case drawing::TextHorizontalAdjust::TextHorizontalAdjust_RIGHT:
496  xFrameParaProps->setPropertyValue(
498  uno::makeAny(style::ParagraphAdjust::ParagraphAdjust_RIGHT)); //1
499  break;
500  default:
501  SAL_WARN("sw.core",
502  "SwTextBoxHelper::syncProperty: unhandled TextHorizontalAdjust: "
503  << static_cast<sal_Int32>(eValue));
504  break;
505  }
506  return;
507  }
508 
509  if (rPropertyName == u"CustomShapeGeometry")
510  {
511  // CustomShapeGeometry changes the textbox position offset and size, so adjust both.
512  syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::Any());
513 
514  SdrObject* pObject = pObj ? pObj : pShape->FindRealSdrObject();
515  if (pObject)
516  {
517  tools::Rectangle aRectangle(pObject->GetSnapRect());
518  syncProperty(
520  uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Left()))));
521  syncProperty(
523  uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top()))));
524  }
525 
526  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
527  if (!pFormat)
528  return;
529 
530  comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue);
531  auto it = aCustomShapeGeometry.find("TextPreRotateAngle");
532  if (it == aCustomShapeGeometry.end())
533  {
534  it = aCustomShapeGeometry.find("TextRotateAngle");
535  }
536 
537  if (it != aCustomShapeGeometry.end())
538  {
539  auto nAngle = it->second.has<sal_Int32>() ? it->second.get<sal_Int32>() : 0;
540  if (nAngle == 0)
541  {
542  nAngle = it->second.has<double>() ? it->second.get<double>() : 0;
543  }
544 
545  sal_Int16 nDirection = 0;
546  switch (nAngle)
547  {
548  case -90:
549  nDirection = text::WritingMode2::TB_RL;
550  break;
551  case -270:
552  nDirection = text::WritingMode2::BT_LR;
553  break;
554  default:
555  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled property value: "
556  "CustomShapeGeometry:TextPreRotateAngle: "
557  << nAngle);
558  break;
559  }
560 
561  if (nDirection)
562  {
563  syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(nDirection), pObj);
564  }
565  }
566  }
567  else if (rPropertyName == UNO_NAME_TEXT_VERT_ADJUST)
568  syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0, rValue, pObj);
569  else if (rPropertyName == UNO_NAME_TEXT_AUTOGROWHEIGHT)
570  syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, rValue, pObj);
571  else if (rPropertyName == UNO_NAME_TEXT_LEFTDIST)
572  syncProperty(pShape, RES_BOX, LEFT_BORDER_DISTANCE, rValue, pObj);
573  else if (rPropertyName == UNO_NAME_TEXT_RIGHTDIST)
574  syncProperty(pShape, RES_BOX, RIGHT_BORDER_DISTANCE, rValue, pObj);
575  else if (rPropertyName == UNO_NAME_TEXT_UPPERDIST)
576  syncProperty(pShape, RES_BOX, TOP_BORDER_DISTANCE, rValue, pObj);
577  else if (rPropertyName == UNO_NAME_TEXT_LOWERDIST)
578  syncProperty(pShape, RES_BOX, BOTTOM_BORDER_DISTANCE, rValue, pObj);
579  else if (rPropertyName == UNO_NAME_TEXT_WRITINGMODE)
580  {
581  text::WritingMode eMode;
582  sal_Int16 eMode2;
583  if (rValue >>= eMode)
584  syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)), pObj);
585  else if (rValue >>= eMode2)
586  syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(eMode2), pObj);
587  }
588  else
589  SAL_INFO("sw.core", "SwTextBoxHelper::syncProperty: unhandled property: "
590  << static_cast<OUString>(rPropertyName));
591 }
592 
593 void SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
594  css::uno::Any& rValue)
595 {
596  if (!pShape)
597  return;
598 
599  nMemberID &= ~CONVERT_TWIPS;
600 
601  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
602  if (!pFormat)
603  return;
604 
605  if (nWID != RES_CHAIN)
606  return;
607 
608  switch (nMemberID)
609  {
610  case MID_CHAIN_PREVNAME:
611  case MID_CHAIN_NEXTNAME:
612  {
613  const SwFormatChain& rChain = pFormat->GetChain();
614  rChain.QueryValue(rValue, nMemberID);
615  }
616  break;
617  case MID_CHAIN_NAME:
618  rValue <<= pFormat->GetName();
619  break;
620  default:
621  SAL_WARN("sw.core", "SwTextBoxHelper::getProperty: unhandled member-id: "
622  << o3tl::narrowing<sal_uInt16>(nMemberID));
623  break;
624  }
625 }
626 
627 css::uno::Any SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, const OUString& rPropName)
628 {
629  if (!pShape)
630  return {};
631 
632  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
633  if (!pFormat)
634  return {};
635 
636  uno::Reference<beans::XPropertySet> const xPropertySet(
637  SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
638 
639  return xPropertySet->getPropertyValue(rPropName);
640 }
641 
642 void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
643  const css::uno::Any& rValue, SdrObject* pObj)
644 {
645  // No shape yet? Then nothing to do, initial properties are set by create().
646  if (!pShape)
647  return;
648 
649  uno::Any aValue(rValue);
650  nMemberID &= ~CONVERT_TWIPS;
651 
652  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
653  if (!pFormat)
654  return;
655 
656  OUString aPropertyName;
657  bool bAdjustX = false;
658  bool bAdjustY = false;
659  bool bAdjustSize = false;
660  switch (nWID)
661  {
662  case RES_HORI_ORIENT:
663  switch (nMemberID)
664  {
666  aPropertyName = UNO_NAME_HORI_ORIENT;
667  break;
669  if (pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)
670  aPropertyName = UNO_NAME_HORI_ORIENT_RELATION;
671  else
672  return;
673  break;
675  aPropertyName = UNO_NAME_HORI_ORIENT_POSITION;
676  bAdjustX = true;
677  break;
678  default:
679  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
680  << o3tl::narrowing<sal_uInt16>(nMemberID)
681  << " (which-id: " << nWID << ")");
682  break;
683  }
684  break;
685  case RES_LR_SPACE:
686  {
687  switch (nMemberID)
688  {
689  case MID_L_MARGIN:
690  aPropertyName = UNO_NAME_LEFT_MARGIN;
691  break;
692  case MID_R_MARGIN:
693  aPropertyName = UNO_NAME_RIGHT_MARGIN;
694  break;
695  default:
696  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
697  << o3tl::narrowing<sal_uInt16>(nMemberID)
698  << " (which-id: " << nWID << ")");
699  break;
700  }
701  break;
702  }
703  case RES_VERT_ORIENT:
704  switch (nMemberID)
705  {
707  aPropertyName = UNO_NAME_VERT_ORIENT;
708  break;
710  if (pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)
711  aPropertyName = UNO_NAME_VERT_ORIENT_RELATION;
712  else
713  return;
714  break;
716  aPropertyName = UNO_NAME_VERT_ORIENT_POSITION;
717  bAdjustY = true;
718  break;
719  default:
720  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
721  << o3tl::narrowing<sal_uInt16>(nMemberID)
722  << " (which-id: " << nWID << ")");
723  break;
724  }
725  break;
726  case RES_FRM_SIZE:
727  switch (nMemberID)
728  {
730  aPropertyName = UNO_NAME_WIDTH_TYPE;
731  break;
733  aPropertyName = UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT;
734  break;
736  aPropertyName = UNO_NAME_RELATIVE_HEIGHT_RELATION;
737  break;
739  aPropertyName = UNO_NAME_RELATIVE_WIDTH_RELATION;
740  break;
741  default:
742  aPropertyName = UNO_NAME_SIZE;
743  bAdjustSize = true;
744  break;
745  }
746  break;
747  case RES_ANCHOR:
748  switch (nMemberID)
749  {
751  {
752  setWrapThrough(pShape);
753  changeAnchor(pShape, pObj);
754  doTextBoxPositioning(pShape, pObj);
755 
756  return;
757  }
758  break;
759  default:
760  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
761  << o3tl::narrowing<sal_uInt16>(nMemberID)
762  << " (which-id: " << nWID << ")");
763  break;
764  }
765  break;
766  case FN_TEXT_RANGE:
767  {
768  uno::Reference<text::XTextRange> xRange;
769  rValue >>= xRange;
770  SwUnoInternalPaM aInternalPaM(*pFormat->GetDoc());
771  if (sw::XTextRangeToSwPaM(aInternalPaM, xRange))
772  {
773  SwFormatAnchor aAnchor(pFormat->GetAnchor());
774  aAnchor.SetAnchor(aInternalPaM.Start());
775  pFormat->SetFormatAttr(aAnchor);
776  }
777  }
778  break;
779  case RES_CHAIN:
780  switch (nMemberID)
781  {
782  case MID_CHAIN_PREVNAME:
783  aPropertyName = UNO_NAME_CHAIN_PREV_NAME;
784  break;
785  case MID_CHAIN_NEXTNAME:
786  aPropertyName = UNO_NAME_CHAIN_NEXT_NAME;
787  break;
788  default:
789  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
790  << o3tl::narrowing<sal_uInt16>(nMemberID)
791  << " (which-id: " << nWID << ")");
792  break;
793  }
794  break;
796  aPropertyName = UNO_NAME_TEXT_VERT_ADJUST;
797  break;
798  case RES_BOX:
799  switch (nMemberID)
800  {
802  aPropertyName = UNO_NAME_LEFT_BORDER_DISTANCE;
803  break;
805  aPropertyName = UNO_NAME_RIGHT_BORDER_DISTANCE;
806  break;
807  case TOP_BORDER_DISTANCE:
808  aPropertyName = UNO_NAME_TOP_BORDER_DISTANCE;
809  break;
811  aPropertyName = UNO_NAME_BOTTOM_BORDER_DISTANCE;
812  break;
813  default:
814  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
815  << o3tl::narrowing<sal_uInt16>(nMemberID)
816  << " (which-id: " << nWID << ")");
817  break;
818  }
819  break;
820  case RES_OPAQUE:
821  aPropertyName = UNO_NAME_OPAQUE;
822  break;
823  case RES_FRAMEDIR:
824  aPropertyName = UNO_NAME_WRITING_MODE;
825  break;
827  switch (nMemberID)
828  {
829  case MID_ALLOW_OVERLAP:
830  aPropertyName = UNO_NAME_ALLOW_OVERLAP;
831  break;
832  default:
833  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
834  << o3tl::narrowing<sal_uInt16>(nMemberID)
835  << " (which-id: " << nWID << ")");
836  break;
837  }
838  break;
839  default:
840  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled which-id: "
841  << nWID << " (member-id: "
842  << o3tl::narrowing<sal_uInt16>(nMemberID) << ")");
843  break;
844  }
845 
846  if (aPropertyName.isEmpty())
847  return;
848 
849  // Position/size should be the text position/size, not the shape one as-is.
850  if (bAdjustX || bAdjustY || bAdjustSize)
851  {
852  changeAnchor(pShape, pObj);
853  tools::Rectangle aRect
854  = getTextRectangle(pObj ? pObj : pShape->FindRealSdrObject(), /*bAbsolute=*/false);
855  if (!aRect.IsEmpty())
856  {
857  if (bAdjustX || bAdjustY)
858  {
859  sal_Int32 nValue;
860  if (aValue >>= nValue)
861  {
862  nValue += convertTwipToMm100(bAdjustX ? aRect.Left() : aRect.Top());
863  aValue <<= nValue;
864  }
865  }
866  else if (bAdjustSize)
867  {
868  awt::Size aSize(convertTwipToMm100(aRect.getWidth()),
869  convertTwipToMm100(aRect.getHeight()));
870  aValue <<= aSize;
871  }
872  }
873  }
874 
875  uno::Reference<beans::XPropertySet> const xPropertySet(
876  SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
877  xPropertySet->setPropertyValue(aPropertyName, aValue);
878 }
879 
881  std::map<const SwFrameFormat*, const SwFrameFormat*>& rLinks)
882 {
883  for (const auto pFormat : rFormats)
884  {
885  if (SwFrameFormat* pTextBox = getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
886  rLinks[pFormat] = pTextBox;
887  }
888 }
889 
890 void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrameFormat*>& rNew,
891  SavedLink& rSavedLinks)
892 {
893  std::size_t i = 0;
894  for (const auto& rIt : rOld)
895  {
896  auto aTextBoxIt = rSavedLinks.find(rIt.GetFormat());
897  if (aTextBoxIt != rSavedLinks.end())
898  {
899  std::size_t j = 0;
900  for (const auto& rJt : rOld)
901  {
902  if (rJt.GetFormat() == aTextBoxIt->second)
903  rNew[i]->SetFormatAttr(rNew[j]->GetContent());
904  ++j;
905  }
906  }
907  ++i;
908  }
909 }
910 
911 text::TextContentAnchorType SwTextBoxHelper::mapAnchorType(const RndStdIds& rAnchorID)
912 {
913  text::TextContentAnchorType aAnchorType;
914  switch (rAnchorID)
915  {
916  case RndStdIds::FLY_AS_CHAR:
917  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AS_CHARACTER;
918  break;
919  case RndStdIds::FLY_AT_CHAR:
920  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_CHARACTER;
921  break;
922  case RndStdIds::FLY_AT_PARA:
923  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH;
924  break;
925  case RndStdIds::FLY_AT_PAGE:
926  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PAGE;
927  break;
928  case RndStdIds::FLY_AT_FLY:
929  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_FRAME;
930  break;
931  default:
932  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH;
933  SAL_WARN("sw.core", "SwTextBoxHelper::mapAnchorType: Unknown AnchorType!");
934  break;
935  }
936  return aAnchorType;
937 }
938 
940  SdrObject* pObj)
941 {
942  SwFrameFormat* pFormat = getOtherTextBoxFormat(&rShape, RES_DRAWFRMFMT, pObj);
943  if (!pFormat)
944  return;
945 
946  const bool bInlineAnchored = rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR;
947  SfxItemSet aTextBoxSet(pFormat->GetDoc()->GetAttrPool(), aFrameFormatSetRange);
948 
949  SfxItemIter aIter(rSet);
950  const SfxPoolItem* pItem = aIter.GetCurItem();
951 
952  do
953  {
954  switch (pItem->Which())
955  {
956  case RES_VERT_ORIENT:
957  {
958  // The new position can be with anchor changing so sync it!
959  const text::TextContentAnchorType aNewAnchorType
960  = mapAnchorType(rShape.GetAnchor().GetAnchorId());
961  syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType),
962  pObj);
963  if (bInlineAnchored)
964  return;
966 
967  tools::Rectangle aRect = getTextRectangle(pObj ? pObj : rShape.FindRealSdrObject(),
968  /*bAbsolute=*/false);
969  if (!aRect.IsEmpty())
970  aOrient.SetPos(aOrient.GetPos() + aRect.Top());
971 
972  if (rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
973  && rShape.GetAnchor().GetPageNum() != 0)
974  aOrient.SetRelationOrient(rShape.GetVertOrient().GetRelationOrient());
975  aTextBoxSet.Put(aOrient);
976 
977  // restore height (shrunk for extending beyond the page bottom - tdf#91260)
978  SwFormatFrameSize aSize(pFormat->GetFrameSize());
979  if (!aRect.IsEmpty())
980  {
981  aSize.SetHeight(aRect.getHeight());
982  aTextBoxSet.Put(aSize);
983  }
984  }
985  break;
986  case RES_HORI_ORIENT:
987  {
988  // The new position can be with anchor changing so sync it!
989  const text::TextContentAnchorType aNewAnchorType
990  = mapAnchorType(rShape.GetAnchor().GetAnchorId());
991  syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType),
992  pObj);
993  if (bInlineAnchored)
994  return;
996 
997  tools::Rectangle aRect = getTextRectangle(pObj ? pObj : rShape.FindRealSdrObject(),
998  /*bAbsolute=*/false);
999  if (!aRect.IsEmpty())
1000  aOrient.SetPos(aOrient.GetPos() + aRect.Left());
1001 
1002  if (rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
1003  && rShape.GetAnchor().GetPageNum() != 0)
1004  aOrient.SetRelationOrient(rShape.GetHoriOrient().GetRelationOrient());
1005  aTextBoxSet.Put(aOrient);
1006  }
1007  break;
1008  case RES_FRM_SIZE:
1009  {
1010  // In case the shape got resized, then we need to adjust both
1011  // the position and the size of the textbox (e.g. larger
1012  // rounded edges of a rectangle -> need to push right/down the
1013  // textbox).
1014  SwFormatVertOrient aVertOrient(rShape.GetVertOrient());
1015  SwFormatHoriOrient aHoriOrient(rShape.GetHoriOrient());
1016  SwFormatFrameSize aSize(pFormat->GetFrameSize());
1017 
1018  tools::Rectangle aRect = getTextRectangle(pObj ? pObj : rShape.FindRealSdrObject(),
1019  /*bAbsolute=*/false);
1020  if (!aRect.IsEmpty())
1021  {
1022  if (!bInlineAnchored)
1023  {
1024  aVertOrient.SetPos(
1025  (pObj ? pObj->GetRelativePos().getX() : aVertOrient.GetPos())
1026  + aRect.Top());
1027  aHoriOrient.SetPos(
1028  (pObj ? pObj->GetRelativePos().getY() : aHoriOrient.GetPos())
1029  + aRect.Left());
1030 
1031  aTextBoxSet.Put(aVertOrient);
1032  aTextBoxSet.Put(aHoriOrient);
1033  }
1034 
1035  aSize.SetWidth(aRect.getWidth());
1036  aSize.SetHeight(aRect.getHeight());
1037  aTextBoxSet.Put(aSize);
1038  }
1039  }
1040  break;
1041  case RES_ANCHOR:
1042  {
1043  if (pItem->StaticWhichCast(RES_ANCHOR) == rShape.GetAnchor())
1044  // the anchor have to be synced
1045  {
1046  const text::TextContentAnchorType aNewAnchorType
1047  = mapAnchorType(rShape.GetAnchor().GetAnchorId());
1048  syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE,
1049  uno::Any(aNewAnchorType), pObj);
1050  }
1051  else
1052  {
1053  SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrameAttr: The anchor of the "
1054  "shape different from the textframe!");
1055  }
1056  }
1057  break;
1058  default:
1059  SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrameAttr: unhandled which-id: "
1060  << pItem->Which());
1061  break;
1062  }
1063 
1064  pItem = aIter.NextItem();
1065  } while (pItem && (0 != pItem->Which()));
1066 
1067  if (aTextBoxSet.Count())
1068  pFormat->SetFormatAttr(aTextBoxSet);
1069  //pFormat->GetDoc()->SetFlyFrameAttr(*pFormat, aTextBoxSet);
1070 
1071  DoTextBoxZOrderCorrection(&rShape, pObj);
1072 }
1073 
1075 {
1076  if (!pObj)
1077  return;
1078  uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY);
1079  if (!xShape)
1080  return;
1081  uno::Reference<beans::XPropertySet> const xPropertySet(xShape, uno::UNO_QUERY);
1082 
1083  auto pParentFormat = getOtherTextBoxFormat(getOtherTextBoxFormat(xShape), RES_FLYFRMFMT);
1084  if (!pParentFormat)
1085  return;
1086 
1087  // Sync the padding
1088  syncProperty(pParentFormat, UNO_NAME_TEXT_LEFTDIST,
1089  xPropertySet->getPropertyValue(UNO_NAME_TEXT_LEFTDIST));
1090  syncProperty(pParentFormat, UNO_NAME_TEXT_RIGHTDIST,
1091  xPropertySet->getPropertyValue(UNO_NAME_TEXT_RIGHTDIST));
1092  syncProperty(pParentFormat, UNO_NAME_TEXT_UPPERDIST,
1093  xPropertySet->getPropertyValue(UNO_NAME_TEXT_UPPERDIST));
1094  syncProperty(pParentFormat, UNO_NAME_TEXT_LOWERDIST,
1095  xPropertySet->getPropertyValue(UNO_NAME_TEXT_LOWERDIST));
1096 
1097  // Sync the text aligning
1098  syncProperty(pParentFormat, UNO_NAME_TEXT_VERTADJUST,
1099  xPropertySet->getPropertyValue(UNO_NAME_TEXT_VERTADJUST));
1100  syncProperty(pParentFormat, UNO_NAME_TEXT_HORZADJUST,
1101  xPropertySet->getPropertyValue(UNO_NAME_TEXT_HORZADJUST));
1102 
1103  // tdf137803: Sync autogrow:
1104  const bool bIsAutoGrow
1105  = xPropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT).get<bool>();
1106  const bool bIsAutoWrap = xPropertySet->getPropertyValue(UNO_NAME_TEXT_WORDWRAP).get<bool>();
1107 
1108  syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, uno::Any(bIsAutoGrow));
1109 
1110  syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_WIDTH_TYPE,
1111  uno::Any(bIsAutoWrap ? text::SizeType::FIX : text::SizeType::MIN));
1112 
1113  changeAnchor(pParentFormat, pObj);
1114  DoTextBoxZOrderCorrection(pParentFormat, pObj);
1115 }
1116 
1118 {
1119  OUString sErrMsg;
1120  if (isTextBoxShapeHasValidTextFrame(pShape))
1121  {
1122  if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
1123  {
1124  ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
1125  if (auto xFrame = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat))
1126  try
1127  {
1128  uno::Reference<beans::XPropertySet> const xPropertySet(xFrame, uno::UNO_QUERY);
1129  xPropertySet->setPropertyValue(UNO_NAME_SURROUND,
1130  uno::makeAny(text::WrapTextMode_THROUGH));
1131  return true;
1132  }
1133  catch (uno::Exception& e)
1134  {
1135  sErrMsg = "Exception caught: " + e.Message;
1136  }
1137  else
1138  sErrMsg = "No XTextFrame!";
1139  }
1140  else
1141  sErrMsg = "No Other TextBox Format!";
1142  }
1143  else
1144  sErrMsg = "Not a Valid TextBox object!";
1145 
1146  SAL_WARN("sw.core", "SwTextBoxHelper::setWrapThrough: " << sErrMsg);
1147  return false;
1148 }
1149 
1151 {
1152  if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
1153  {
1154  const SwFormatAnchor& rOldAnch = pFormat->GetAnchor();
1155  const SwFormatAnchor& rNewAnch = pShape->GetAnchor();
1156 
1157  const auto pOldCnt = rOldAnch.GetContentAnchor();
1158  const auto pNewCnt = rNewAnch.GetContentAnchor();
1159 
1160  const uno::Any aShapeHorRelOrient
1162 
1163  if (isAnchorTypeDifferent(pShape) || (pObj && pObj != pShape->FindRealSdrObject()))
1164  {
1165  try
1166  {
1167  ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
1168  uno::Reference<beans::XPropertySet> const xPropertySet(
1169  SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
1170  if (pOldCnt && rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
1171  && rNewAnch.GetPageNum())
1172  {
1173  uno::Any aValue(text::TextContentAnchorType_AT_PAGE);
1174  xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1175  aShapeHorRelOrient);
1176  xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1177  xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO,
1178  uno::Any(rNewAnch.GetPageNum()));
1179  }
1180  else if (rOldAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE && pNewCnt)
1181  {
1182  if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1183  {
1184  uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
1185  xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1186  xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1187  uno::Any(text::RelOrientation::CHAR));
1188  xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
1189  uno::Any(text::RelOrientation::PRINT_AREA));
1190  SwFormatAnchor aPos(pFormat->GetAnchor());
1191  aPos.SetAnchor(pNewCnt);
1192  pFormat->SetFormatAttr(aPos);
1193  }
1194  else
1195  {
1196  uno::Any aValue(mapAnchorType(rNewAnch.GetAnchorId()));
1197  xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1198  aShapeHorRelOrient);
1199  xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1200  pFormat->SetFormatAttr(rNewAnch);
1201  }
1202  }
1203  else
1204  {
1205  if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1206  {
1207  uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
1208  xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1209  xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1210  uno::Any(text::RelOrientation::CHAR));
1211  xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
1212  uno::Any(text::RelOrientation::PRINT_AREA));
1213  SwFormatAnchor aPos(pFormat->GetAnchor());
1214  aPos.SetAnchor(pNewCnt);
1215  pFormat->SetFormatAttr(aPos);
1216  }
1217  else
1218  {
1219  xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1220  aShapeHorRelOrient);
1221  pFormat->SetFormatAttr(pShape->GetAnchor());
1222  }
1223  }
1224  }
1225  catch (uno::Exception& e)
1226  {
1227  SAL_WARN("sw.core", "SwTextBoxHelper::changeAnchor(): " << e.Message);
1228  }
1229  }
1230 
1231  return doTextBoxPositioning(pShape, pObj) && DoTextBoxZOrderCorrection(pShape, pObj);
1232  }
1233 
1234  return false;
1235 }
1236 
1238 {
1239  const bool bIsGroupObj = (pObj != pShape->FindRealSdrObject()) && pObj;
1240  if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
1241  {
1242  ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
1243  if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1244  {
1245  tools::Rectangle aRect(
1246  getTextRectangle(pObj ? pObj : pShape->FindRealSdrObject(), false));
1247 
1248  auto nLeftSpace = pShape->GetLRSpace().GetLeft();
1249 
1250  SwFormatHoriOrient aNewHOri(pFormat->GetHoriOrient());
1251  aNewHOri.SetPos(aRect.Left() + nLeftSpace);
1252 
1253  SwFormatVertOrient aNewVOri(pFormat->GetVertOrient());
1254  aNewVOri.SetPos(aRect.Top() + pShape->GetVertOrient().GetPos());
1255 
1256  // tdf#140598: Do not apply wrong rectangle position.
1257  if (aRect.TopLeft() != Point(0, 0))
1258  {
1259  pFormat->SetFormatAttr(aNewHOri);
1260  pFormat->SetFormatAttr(aNewVOri);
1261  }
1262  else
1263  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
1264  }
1265  else
1266  {
1267  tools::Rectangle aRect(
1268  getTextRectangle(pObj ? pObj : pShape->FindRealSdrObject(), false));
1269 
1270  // tdf#140598: Do not apply wrong rectangle position.
1271  if (aRect.TopLeft() != Point(0, 0) || bIsGroupObj)
1272  {
1273  SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
1274  aNewHOri.SetPos(
1275  (bIsGroupObj && pObj ? pObj->GetRelativePos().getX() : aNewHOri.GetPos())
1276  + aRect.Left());
1277  SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
1278  aNewVOri.SetPos(
1279  (bIsGroupObj && pObj ? pObj->GetRelativePos().getY() : aNewVOri.GetPos())
1280  + aRect.Top());
1281 
1282  pFormat->SetFormatAttr(aNewHOri);
1283  pFormat->SetFormatAttr(aNewVOri);
1284  }
1285  else
1286  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: Repositioning failed!");
1287  }
1288  return true;
1289  }
1290 
1291  return false;
1292 }
1293 
1294 std::optional<bool> SwTextBoxHelper::isAnchorTypeDifferent(const SwFrameFormat* pShape)
1295 {
1296  std::optional<bool> bRet;
1297  if (isTextBoxShapeHasValidTextFrame(pShape))
1298  {
1299  if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
1300  {
1301  if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1302  bRet = (pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AT_CHAR
1303  && pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR);
1304  else
1305  bRet = pFormat->GetAnchor().GetAnchorId() != pShape->GetAnchor().GetAnchorId();
1306  }
1307  }
1308  return bRet;
1309 }
1310 
1312 {
1313  if (pShape && pShape->Which() == RES_DRAWFRMFMT)
1314  if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
1315  if (pFormat && pFormat->Which() == RES_FLYFRMFMT)
1316  return true;
1317  else
1318  SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: "
1319  "Shape does not have valid textframe!");
1320  else
1321  SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: "
1322  "Shape does not have associated frame!");
1323  else
1324  SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: Not valid shape!");
1325  return false;
1326 }
1327 
1329 {
1330  // TODO: do this with group shape textboxes.
1331  SdrObject* pShpObj = nullptr;
1332  //if (pObj)
1333  // pShpObj = pObj;
1334  //else
1335  pShpObj = pShape->FindRealSdrObject();
1336 
1337  if (pShpObj)
1338  {
1339  if (SdrObject* pFrmObj
1340  = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj)->FindRealSdrObject())
1341  {
1342  // Get the draw model from the doc
1343  SwDrawModel* pDrawModel
1345  if (pDrawModel)
1346  {
1347  // Not really sure this will work all page, but it seems it will.
1348  auto pPage = pDrawModel->GetPage(0);
1349  // Recalc all Zorders
1350  pPage->RecalcObjOrdNums();
1351  // Here is a counter avoiding running to in infinity:
1352  sal_uInt16 nIterator = 0;
1353  // If the shape is behind the frame, is good, but if there are some objects
1354  // between of them that is wrong so put the frame exactly one level higher
1355  // than the shape.
1356  if (pFrmObj->GetOrdNum() > pShpObj->GetOrdNum())
1357  pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pShpObj->GetOrdNum() + 1);
1358  else
1359  // Else, if the frame is behind the shape, bring to the front of it.
1360  while (pFrmObj->GetOrdNum() <= pShpObj->GetOrdNum())
1361  {
1362  pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pFrmObj->GetOrdNum() + 1);
1363  // If there is any problem with the indexes, do not run over the infinity
1364  if (pPage->GetObjCount() == pFrmObj->GetOrdNum())
1365  break;
1366  ++nIterator;
1367  if (nIterator > 300)
1368  break; // Do not run to infinity
1369  }
1370  pPage->RecalcObjOrdNums();
1371  return true; // Success
1372  }
1373  SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1374  "No Valid Draw model for SdrObject for the shape!");
1375  }
1376  SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1377  "No Valid SdrObject for the frame!");
1378  }
1379  SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1380  "No Valid SdrObject for the shape!");
1381 
1382  return false;
1383 }
1384 
1386 {
1387  assert(pOwnerShape);
1388  assert(pOwnerShape->Which() == RES_DRAWFRMFMT);
1389 
1390  m_pOwnerShapeFormat = pOwnerShape;
1391  if (!m_pTextBoxes.empty())
1392  m_pTextBoxes.clear();
1393 }
1394 
1396 {
1397  m_pTextBoxes.clear();
1398 
1399  if (m_pOwnerShapeFormat && m_pOwnerShapeFormat->GetOtherTextBoxFormat())
1400  m_pOwnerShapeFormat->SetOtherTextBoxFormat(nullptr);
1401 }
1402 
1403 void SwTextBoxNode::AddTextBox(SdrObject* pDrawObject, SwFrameFormat* pNewTextBox)
1404 {
1405  assert(pNewTextBox);
1406  assert(pNewTextBox->Which() == RES_FLYFRMFMT);
1407 
1408  assert(pDrawObject);
1409 
1410  SwTextBoxElement aElem;
1411  aElem.m_bIsActive = true;
1412  aElem.m_pDrawObject = pDrawObject;
1413  aElem.m_pTextBoxFormat = pNewTextBox;
1414  SwFlyDrawObj* pSwFlyDraw = dynamic_cast<SwFlyDrawObj*>(pDrawObject);
1415  if (pSwFlyDraw)
1416  {
1417  pSwFlyDraw->SetTextBox(true);
1418  }
1419  m_pTextBoxes.push_back(aElem);
1420 }
1421 
1422 void SwTextBoxNode::DelTextBox(const SdrObject* pDrawObject)
1423 {
1424  assert(pDrawObject);
1425  if (!m_pTextBoxes.empty())
1426  {
1427  for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end();)
1428  {
1429  if (it->m_pDrawObject == pDrawObject)
1430  {
1431  m_pOwnerShapeFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(
1432  it->m_pTextBoxFormat);
1433  it = m_pTextBoxes.erase(it);
1434  break;
1435  }
1436  else
1437  ++it;
1438  }
1439  }
1440 }
1441 
1443 {
1444  assert(pDrawObject);
1445  if (!m_pTextBoxes.empty())
1446  {
1447  for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
1448  {
1449  if (it->m_pDrawObject == pDrawObject)
1450  {
1451  return it->m_pTextBoxFormat;
1452  }
1453  }
1454  }
1455  return nullptr;
1456 }
1457 
1458 bool SwTextBoxNode::IsTextBoxActive(const SdrObject* pDrawObject) const
1459 {
1460  assert(pDrawObject);
1461 
1462  if (!m_pTextBoxes.empty())
1463  {
1464  for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
1465  {
1466  if (it->m_pDrawObject == pDrawObject)
1467  {
1468  return it->m_bIsActive;
1469  }
1470  }
1471  }
1472  return false;
1473 }
1474 
1476 {
1477  assert(pDrawObject);
1478 
1479  if (!m_pTextBoxes.empty())
1480  {
1481  for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
1482  {
1483  if (it->m_pDrawObject == pDrawObject)
1484  {
1485  it->m_bIsActive = true;
1486  }
1487  }
1488  }
1489 }
1490 
1492 {
1493  assert(pDrawObject);
1494 
1495  if (!m_pTextBoxes.empty())
1496  {
1497  for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
1498  {
1499  if (it->m_pDrawObject == pDrawObject)
1500  {
1501  it->m_bIsActive = false;
1502  }
1503  }
1504  }
1505 }
1506 
1507 bool SwTextBoxNode::IsGroupTextBox() const { return m_pTextBoxes.size() > 1; }
1508 
1509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
If we have an associated TextFrame, then return that.
static bool isTextBoxShapeHasValidTextFrame(const SwFrameFormat *pShape)
Returns true if the given shape has a valid textframe.
void SetTextBox(bool bIsTextBox)
Definition: dflyobj.hxx:52
void SetPos(const Point &rPoint)
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
#define MID_CHAIN_NAME
Definition: unomid.h:58
const css::uno::WeakReference< css::uno::XInterface > & getWeakUnoShape() const
#define UNO_NAME_TEXT_WORDWRAP
static sal_Int32 getCount(const SwDoc &rDoc)
Count number of shapes in the document, excluding TextBoxes.
static std::optional< bool > isAnchorTypeDifferent(const SwFrameFormat *pShape)
Returns true if the anchor different for the given shape, and the associated textframe of the given s...
SwFrameFormat * GetTextBox(const SdrObject *pDrawObject) const
static css::uno::Any getByIndex(SdrPage const *pPage, sal_Int32 nIndex)
Get a shape by index, excluding TextBoxes.
virtual const tools::Rectangle & GetCurrentBoundRect() const
void SetHeight(tools::Long n)
#define UNO_NAME_HORI_ORIENT_POSITION
Definition: unoprnms.hxx:265
#define UNO_NAME_TEXT_RIGHTDIST
SwDocShell * GetDocShell()
Definition: doc.hxx:1352
#define UNO_NAME_BOTTOM_BORDER
Definition: unoprnms.hxx:358
tools::Long getWidth() const
static bool hasTextFrame(const SdrObject *pObj)
Returns true if the SdrObject has a SwTextFrame otherwise false.
#define UNO_NAME_RELATIVE_HEIGHT_RELATION
Definition: unoprnms.hxx:191
constexpr tools::Long Left() const
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
Definition: atrfrm.cxx:2147
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:106
#define UNO_NAME_IS_FOLLOWING_TEXT_FLOW
Definition: unoprnms.hxx:741
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
#define UNO_NAME_ALLOW_OVERLAP
Definition: unoprnms.hxx:867
constexpr TypedWhichId< SdrTextVertAdjustItem > RES_TEXT_VERT_ADJUST(130)
sal_uInt16 GetPageNum() const
Definition: fmtanchr.hxx:66
virtual void SetModified()=0
Must be called manually at changes of format.
Reference< XFrame > xFrame
virtual Point GetRelativePos() const
#define MID_VERTORIENT_RELATION
Definition: unomid.h:35
static sal_Int32 getOrdNum(const SdrObject *pObject)
Get the order of the shape, excluding TextBoxes.
#define UNO_NAME_TEXT_LOWERDIST
SdrObject * GetObj(size_t nNum) const
void RecalcObjOrdNums()
Definition: doc.hxx:188
virtual bool IsTextBox() const
size_t GetObjCount() const
OUString GetUniqueFrameName() const
Definition: doclay.cxx:1379
#define RIGHT_BORDER_DISTANCE
Textboxes are basically textframe + shape pairs.
void SetOtherTextBoxFormat(SwTextBoxNode *pNew)
Definition: frmfmt.hxx:106
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
constexpr TypedWhichId< SvxOpaqueItem > RES_OPAQUE(99)
#define UNO_NAME_WRITING_MODE
Definition: unoprnms.hxx:691
#define UNO_NAME_ANCHOR_PAGE_NO
Definition: unoprnms.hxx:228
#define UNO_NAME_VERT_ORIENT
Definition: unoprnms.hxx:330
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:144
#define UNO_NAME_TEXT_UPPERDIST
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:55
EmbeddedObjectRef * pObject
WhichRangesContainer const aFrameFormatSetRange(svl::Items< RES_FRMATR_BEGIN, RES_FRMATR_END-1, RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, XATTR_FILL_FIRST, XATTR_FILL_LAST >)
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:744
std::map< const SwFrameFormat *, const SwFrameFormat * > SavedLink
Maps a draw format to a fly format.
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(156)
static css::uno::Any queryInterface(const SwFrameFormat *pShape, const css::uno::Type &rType)
Get interface of a shape's TextBox, if there is any.
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:155
void AddTextBox(SdrObject *pDrawObject, SwFrameFormat *pNewTextBox)
virtual const tools::Rectangle & GetSnapRect() const
constexpr auto convertTwipToMm100(N n)
tools::Long getHeight() const
static css::uno::Reference< css::text::XTextFrame > getUnoTextFrame(css::uno::Reference< css::drawing::XShape > const &xShape)
If we have an associated TextFrame, then return its XTextFrame.
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
#define UNO_NAME_RELATIVE_WIDTH_RELATION
Definition: unoprnms.hxx:189
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(159)
#define UNO_NAME_CHAIN_NEXT_NAME
Definition: unoprnms.hxx:232
virtual css::uno::Reference< css::uno::XInterface > getUnoShape()
#define MID_FRMSIZE_SIZE
Definition: unomid.h:70
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(103)
SdrPage * getSdrPageFromSdrObject() const
#define MID_FOLLOW_TEXT_FLOW
Definition: unomid.h:152
static bool setWrapThrough(SwFrameFormat *pShape)
Sets the surround to through for the textframe of the given shape, not to interfere with the layout...
const OUString & GetName() const
Definition: format.hxx:115
int nCount
#define UNO_NAME_SIZE
Definition: unoprnms.hxx:304
Mode eMode
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
Is the frame format a text box?
#define UNO_NAME_VERT_ORIENT_RELATION
Definition: unoprnms.hxx:333
#define UNO_NAME_TEXT_WRITINGMODE
#define FN_TEXT_RANGE
Definition: cmdid.h:808
constexpr TypedWhichId< SwFormatWrapInfluenceOnObjPos > RES_WRAP_INFLUENCE_ON_OBJPOS(125)
Specific frame formats (frames, DrawObjects).
constexpr bool IsEmpty() const
#define LEFT_BORDER_DISTANCE
static void saveLinks(const SwFrameFormats &rFormats, std::map< const SwFrameFormat *, const SwFrameFormat * > &rLinks)
Saves the current shape -> textbox links in a map, so they can be restored later. ...
static void lcl_queryInterface(const SwFrameFormat *pShape, uno::Any &rAny)
#define UNO_NAME_HORI_ORIENT
Definition: unoprnms.hxx:261
#define MID_CHAIN_NEXTNAME
Definition: unomid.h:57
SwFrameFormat * GetOwnerShape()
#define MID_L_MARGIN
#define MID_ANCHOR_ANCHORTYPE
Definition: unomid.h:43
Style of a layout element.
Definition: frmfmt.hxx:59
#define MID_HORIORIENT_POSITION
Definition: unomid.h:40
static void updateTextBoxMargin(SdrObject *pObj)
Copy shape attributes to the text frame.
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
void DelTextBox(const SdrObject *pDrawObject)
#define UNO_NAME_RIGHT_BORDER
Definition: unoprnms.hxx:356
T & StaticWhichCast(TypedWhichId< T > nId)
#define MID_FRMSIZE_WIDTH_TYPE
Definition: unomid.h:86
#define UNO_NAME_FILL_TRANSPARENCE
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:108
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
static void restoreLinks(std::set< ZSortFly > &rOld, std::vector< SwFrameFormat * > &rNew, SavedLink &rSavedLinks)
Undo the effect of saveLinks() + individual resetLink() calls.
#define UNO_NAME_PARA_ADJUST
Definition: unoprnms.hxx:171
#define MID_VERTORIENT_POSITION
Definition: unomid.h:36
SwTextBoxNode()=delete
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:60
FlyAnchors.
Definition: fmtanchr.hxx:34
tools::Long GetLeft() const
const SdrPage * GetPage(sal_uInt16 nPgNum) const
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
float u
#define BOTTOM_BORDER_DISTANCE
static css::text::TextContentAnchorType mapAnchorType(const RndStdIds &rAnchorID)
There are two types of enum of anchor type, so this function maps this.
static void getProperty(SwFrameFormat const *pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, css::uno::Any &rValue)
Get a property of the underlying TextFrame.
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
sal_uInt32 GetOrdNum() const
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
constexpr tools::Long Top() const
#define UNO_NAME_LEFT_BORDER
Definition: unoprnms.hxx:355
Connection (text flow) between two FlyFrames.
Definition: fmtcnct.hxx:31
#define MID_R_MARGIN
#define MID_FRMSIZE_IS_AUTO_HEIGHT
Definition: unomid.h:77
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:123
static bool changeAnchor(SwFrameFormat *pShape, SdrObject *pObj)
Sets the anchor of the associated textframe of the given shape, and returns true on success...
#define UNO_NAME_LEFT_BORDER_DISTANCE
Definition: unoprnms.hxx:360
#define UNO_NAME_CHAIN_PREV_NAME
Definition: unoprnms.hxx:233
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange,::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1107
#define UNO_NAME_RIGHT_MARGIN
Definition: unoprnms.hxx:69
constexpr Point Center() const
constexpr Point TopLeft() const
#define UNO_NAME_TOP_BORDER
Definition: unoprnms.hxx:357
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:450
#define UNO_NAME_TOP_BORDER_DISTANCE
Definition: unoprnms.hxx:362
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
#define UNO_NAME_TEXT_VERT_ADJUST
Definition: unoprnms.hxx:856
#define UNO_NAME_SURROUND
Definition: unoprnms.hxx:311
#define MID_HORIORIENT_ORIENT
Definition: unomid.h:38
#define MID_FRMSIZE_REL_HEIGHT_RELATION
Definition: unomid.h:88
constexpr Size GetSize() const
constexpr TypedWhichId< SwFormatChain > RES_CHAIN(114)
#define MID_CHAIN_PREVNAME
Definition: unomid.h:56
const SwFormatChain & GetChain(bool=true) const
Definition: fmtcnct.hxx:70
iterator find(const OUString &rKey)
Any makeAny(Color const &value)
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:88
#define UNO_NAME_LEFT_MARGIN
Definition: unoprnms.hxx:68
#define MID_VERTORIENT_ORIENT
Definition: unomid.h:34
unsigned char sal_uInt8
#define UNO_NAME_BOTTOM_BORDER_DISTANCE
Definition: unoprnms.hxx:363
#define UNO_NAME_ANCHOR_TYPE
Definition: unoprnms.hxx:226
bool IsTextBoxActive(const SdrObject *pDrawObject) const
SwTwips GetPos() const
Definition: fmtornt.hxx:59
#define UNO_NAME_TEXT_LEFTDIST
#define MID_FRMSIZE_REL_WIDTH_RELATION
Definition: unomid.h:87
#define SAL_INFO(area, stream)
void SetTextBoxActive(const SdrObject *pDrawObject)
bool IsGroupTextBox() const
static void destroy(const SwFrameFormat *pShape, const SdrObject *pObject)
Destroy a TextBox for a shape.
#define UNO_NAME_HORI_ORIENT_RELATION
Definition: unoprnms.hxx:264
static SW_DLLPUBLIC css::uno::Reference< css::text::XTextFrame > CreateXTextFrame(SwDoc &rDoc, SwFrameFormat *pFrameFormat)
Definition: unoframe.cxx:3177
#define TOP_BORDER_DISTANCE
#define UNO_NAME_TEXT_AUTOGROWHEIGHT
void * p
static css::uno::Reference< css::uno::XInterface > MakeInstance(SwServiceType nObjectType, SwDoc &rDoc)
Definition: unocoll.cxx:513
bool GetTextBounds(tools::Rectangle &rTextBound) const
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
static void syncFlyFrameAttr(SwFrameFormat &rShape, SfxItemSet const &rSet, SdrObject *pObj)
Similar to syncProperty(), but used by the internal API (e.g. for UI purposes).
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
SdrObject * getParentSdrObjectFromSdrObject() const
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:93
#define UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT
Definition: unoprnms.hxx:591
#define MID_HORIORIENT_RELATION
Definition: unomid.h:39
#define UNO_NAME_TEXT_HORZADJUST
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
#define SAL_WARN(area, stream)
RndStdIds
#define UNO_NAME_SIZE_TYPE
Definition: unoprnms.hxx:259
virtual const tools::Rectangle & GetLogicRect() const
static void create(SwFrameFormat *pShape, SdrObject *pObject, bool bCopyText=false)
Create a TextBox for a shape.
static bool DoTextBoxZOrderCorrection(SwFrameFormat *pShape, const SdrObject *pObj)
#define UNO_NAME_RIGHT_BORDER_DISTANCE
Definition: unoprnms.hxx:361
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:120
#define UNO_NAME_WIDTH_TYPE
Definition: unoprnms.hxx:742
#define UNO_NAME_VERT_ORIENT_POSITION
Definition: unoprnms.hxx:332
static tools::Rectangle getTextRectangle(SdrObject *pShape, bool bAbsolute=true)
Return the textbox rectangle of a draw shape (in twips).
static void syncProperty(SwFrameFormat *pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, const css::uno::Any &rValue, SdrObject *pObj=nullptr)
Sync property of TextBox with the one of the shape.
constexpr TypedWhichId< SwFormatFollowTextFlow > RES_FOLLOW_TEXT_FLOW(123)
SwTextBoxNode * GetOtherTextBoxFormat() const
Definition: frmfmt.hxx:105
#define UNO_NAME_OPAQUE
Definition: unoprnms.hxx:283
sal_uInt16 Which() const
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2773
void SetTextBoxInactive(const SdrObject *pDrawObject)
constexpr TypedWhichId< SwFormatAnchor > RES_ANCHOR(104)
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1319
sal_Int16 nValue
#define MID_ALLOW_OVERLAP
Definition: unomid.h:149
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1584
#define CONVERT_TWIPS
static void getShapeWrapThrough(const SwFrameFormat *pTextBox, bool &rWrapThrough)
If pTextBox is a textbox, then set rWrapThrough to the surround of its shape.
static bool doTextBoxPositioning(SwFrameFormat *pShape, SdrObject *pObj)
Does the positioning for the associated textframe of the shape, and returns true on success...
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74
#define UNO_NAME_TEXT_VERTADJUST