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 
32 #include <editeng/unoprnms.hxx>
33 #include <editeng/memberids.h>
34 #include <svx/svdoashp.hxx>
35 #include <svx/svdpage.hxx>
36 #include <svl/itemiter.hxx>
38 #include <sal/log.hxx>
39 #include <tools/UnitConversion.hxx>
40 #include <svx/swframetypes.hxx>
41 
42 #include <com/sun/star/document/XActionLockable.hpp>
43 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
44 #include <com/sun/star/text/SizeType.hpp>
45 #include <com/sun/star/text/TextContentAnchorType.hpp>
46 #include <com/sun/star/text/WrapTextMode.hpp>
47 #include <com/sun/star/text/XTextDocument.hpp>
48 #include <com/sun/star/text/XTextFrame.hpp>
49 #include <com/sun/star/table/BorderLine2.hpp>
50 #include <com/sun/star/text/WritingMode.hpp>
51 #include <com/sun/star/text/WritingMode2.hpp>
52 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
53 #include <com/sun/star/style/ParagraphAdjust.hpp>
54 
55 using namespace com::sun::star;
56 
57 void SwTextBoxHelper::create(SwFrameFormat* pShape, bool bCopyText)
58 {
59  // If TextBox wasn't enabled previously
60  if (pShape->GetAttrSet().HasItem(RES_CNTNT) && pShape->GetOtherTextBoxFormat())
61  return;
62 
63  // Store the current text content of the shape
64  OUString sCopyableText;
65 
66  if (bCopyText)
67  {
68  if (auto pSdrShape = pShape->FindRealSdrObject())
69  {
70  uno::Reference<text::XText> xSrcCnt(pSdrShape->getWeakUnoShape(), uno::UNO_QUERY);
71  auto xCur = xSrcCnt->createTextCursor();
72  xCur->gotoStart(false);
73  xCur->gotoEnd(true);
74  sCopyableText = xCur->getText()->getString();
75  }
76  }
77 
78  // Create the associated TextFrame and insert it into the document.
79  uno::Reference<text::XTextContent> xTextFrame(
81  uno::UNO_QUERY);
82  uno::Reference<text::XTextDocument> xTextDocument(
83  pShape->GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
84  uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(),
85  uno::UNO_QUERY);
86  try
87  {
88  SdrObject* pSourceSDRShape = pShape->FindRealSdrObject();
89  uno::Reference<text::XTextContent> XSourceShape(pSourceSDRShape->getUnoShape(),
90  uno::UNO_QUERY_THROW);
91  xTextContentAppend->insertTextContentWithProperties(
92  xTextFrame, uno::Sequence<beans::PropertyValue>(), XSourceShape->getAnchor());
93  }
94  catch (uno::Exception&)
95  {
96  xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>());
97  }
98  // Link FLY and DRAW formats, so it becomes a text box (needed for syncProperty calls).
99  uno::Reference<text::XTextFrame> xRealTextFrame(xTextFrame, uno::UNO_QUERY);
100  auto pTextFrame = dynamic_cast<SwXTextFrame*>(xRealTextFrame.get());
101  assert(nullptr != pTextFrame);
102  SwFrameFormat* pFormat = pTextFrame->GetFrameFormat();
103 
104  assert(nullptr != dynamic_cast<SwDrawFrameFormat*>(pShape));
105  assert(nullptr != dynamic_cast<SwFlyFrameFormat*>(pFormat));
106 
107  pShape->SetOtherTextBoxFormat(pFormat);
108  pFormat->SetOtherTextBoxFormat(pShape);
109 
110  // Initialize properties.
111  uno::Reference<beans::XPropertySet> xPropertySet(xTextFrame, uno::UNO_QUERY);
112  uno::Any aEmptyBorder = uno::makeAny(table::BorderLine2());
113  xPropertySet->setPropertyValue(UNO_NAME_TOP_BORDER, aEmptyBorder);
114  xPropertySet->setPropertyValue(UNO_NAME_BOTTOM_BORDER, aEmptyBorder);
115  xPropertySet->setPropertyValue(UNO_NAME_LEFT_BORDER, aEmptyBorder);
116  xPropertySet->setPropertyValue(UNO_NAME_RIGHT_BORDER, aEmptyBorder);
117 
118  xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::makeAny(sal_Int32(100)));
119 
120  xPropertySet->setPropertyValue(UNO_NAME_SIZE_TYPE, uno::makeAny(text::SizeType::FIX));
121 
122  xPropertySet->setPropertyValue(UNO_NAME_SURROUND, uno::makeAny(text::WrapTextMode_THROUGH));
123 
124  uno::Reference<container::XNamed> xNamed(xTextFrame, uno::UNO_QUERY);
125  xNamed->setName(pShape->GetDoc()->GetUniqueFrameName());
126 
127  // Link its text range to the original shape.
128  uno::Reference<text::XTextRange> xTextBox(xTextFrame, uno::UNO_QUERY_THROW);
129  SwUnoInternalPaM aInternalPaM(*pShape->GetDoc());
130  if (sw::XTextRangeToSwPaM(aInternalPaM, xTextBox))
131  {
132  SwAttrSet aSet(pShape->GetAttrSet());
133  SwFormatContent aContent(aInternalPaM.GetNode().StartOfSectionNode());
134  aSet.Put(aContent);
135  pShape->SetFormatAttr(aSet);
136  }
137 
138  // Also initialize the properties, which are not constant, but inherited from the shape's ones.
139  uno::Reference<drawing::XShape> xShape(pShape->FindRealSdrObject()->getUnoShape(),
140  uno::UNO_QUERY);
141  syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::makeAny(xShape->getSize()));
142 
143  uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
144  syncProperty(pShape, RES_FOLLOW_TEXT_FLOW, MID_FOLLOW_TEXT_FLOW,
145  xShapePropertySet->getPropertyValue(UNO_NAME_IS_FOLLOWING_TEXT_FLOW));
146  syncProperty(pShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE,
147  xShapePropertySet->getPropertyValue(UNO_NAME_ANCHOR_TYPE));
148  syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_ORIENT,
149  xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT));
150  syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_RELATION,
151  xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_RELATION));
152  syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_ORIENT,
153  xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT));
154  syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_RELATION,
155  xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_RELATION));
156  syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_POSITION,
157  xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_POSITION));
158  syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_POSITION,
159  xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_POSITION));
160  syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT,
161  xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT));
162  syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0,
163  xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_VERT_ADJUST));
164  text::WritingMode eMode;
165  if (xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_WRITINGMODE) >>= eMode)
166  syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)));
167 
168  // TODO: Text dialog attr setting to frame
169 
170  // Check if the shape had text before and move it to the new textframe
171  if (bCopyText && !sCopyableText.isEmpty())
172  {
173  auto pSdrShape = pShape->FindRealSdrObject();
174  if (pSdrShape)
175  {
176  auto pSourceText = dynamic_cast<SdrTextObj*>(pSdrShape);
177  uno::Reference<text::XTextRange> xDestText(xRealTextFrame, uno::UNO_QUERY);
178 
179  xDestText->setString(sCopyableText);
180 
181  if (pSourceText)
182  pSourceText->SetText(OUString());
183 
184  pShape->GetDoc()->getIDocumentState().SetModified();
185  }
186  }
187 }
188 
190 {
191  // If a TextBox was enabled previously
192  if (pShape->GetAttrSet().HasItem(RES_CNTNT))
193  {
194  SwFrameFormat* pFormat = pShape->GetOtherTextBoxFormat();
195 
196  // Unlink the TextBox's text range from the original shape.
197  pShape->ResetFormatAttr(RES_CNTNT);
198 
199  // Delete the associated TextFrame.
200  if (pFormat)
201  pShape->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(pFormat);
202  }
203 }
204 
205 bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pFormat, sal_uInt16 nType)
206 {
207  assert(nType == RES_FLYFRMFMT || nType == RES_DRAWFRMFMT);
208  if (!pFormat || pFormat->Which() != nType || !pFormat->GetAttrSet().HasItem(RES_CNTNT))
209  return false;
210 
211  sal_uInt16 nOtherType = (pFormat->Which() == RES_FLYFRMFMT) ? sal_uInt16(RES_DRAWFRMFMT)
212  : sal_uInt16(RES_FLYFRMFMT);
213  SwFrameFormat* pOtherFormat = pFormat->GetOtherTextBoxFormat();
214  if (!pOtherFormat)
215  return false;
216 
217  assert(pOtherFormat->Which() == nOtherType);
218  if (pOtherFormat->Which() != nOtherType)
219  return false;
220 
221  const SwFormatContent& rContent = pFormat->GetContent();
222  return pOtherFormat->GetAttrSet().HasItem(RES_CNTNT) && pOtherFormat->GetContent() == rContent;
223 }
224 
226 {
227  if (!pObj)
228  return false;
229 
230  uno::Reference<drawing::XShape> xShape(pObj->getWeakUnoShape(), uno::UNO_QUERY);
231  if (!xShape)
232  return false;
234 }
235 
236 sal_Int32 SwTextBoxHelper::getCount(SdrPage const* pPage)
237 {
238  sal_Int32 nRet = 0;
239  for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
240  {
241  SdrObject* p = pPage->GetObj(i);
242  if (p && p->IsTextBox())
243  continue;
244  ++nRet;
245  }
246  return nRet;
247 }
248 
249 sal_Int32 SwTextBoxHelper::getCount(const SwDoc& rDoc)
250 {
251  sal_Int32 nRet = 0;
252  const SwFrameFormats& rSpzFrameFormats = *rDoc.GetSpzFrameFormats();
253  for (const auto pFormat : rSpzFrameFormats)
254  {
255  if (isTextBox(pFormat, RES_FLYFRMFMT))
256  ++nRet;
257  }
258  return nRet;
259 }
260 
261 uno::Any SwTextBoxHelper::getByIndex(SdrPage const* pPage, sal_Int32 nIndex)
262 {
263  if (nIndex < 0)
264  throw lang::IndexOutOfBoundsException();
265 
266  SdrObject* pRet = nullptr;
267  sal_Int32 nCount = 0; // Current logical index.
268  for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
269  {
270  SdrObject* p = pPage->GetObj(i);
271  if (p && p->IsTextBox())
272  continue;
273  if (nCount == nIndex)
274  {
275  pRet = p;
276  break;
277  }
278  ++nCount;
279  }
280 
281  if (!pRet)
282  throw lang::IndexOutOfBoundsException();
283 
284  return uno::makeAny(uno::Reference<drawing::XShape>(pRet->getUnoShape(), uno::UNO_QUERY));
285 }
286 
287 sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject)
288 {
289  if (const SdrPage* pPage = pObject->getSdrPageFromSdrObject())
290  {
291  sal_Int32 nOrder = 0; // Current logical order.
292  for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
293  {
294  SdrObject* p = pPage->GetObj(i);
295  if (p && p->IsTextBox())
296  continue;
297  if (p == pObject)
298  return nOrder;
299  ++nOrder;
300  }
301  }
302 
303  SAL_WARN("sw.core", "SwTextBoxHelper::getOrdNum: no page or page doesn't contain the object");
304  return pObject->GetOrdNum();
305 }
306 
307 void SwTextBoxHelper::getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& rWrapThrough)
308 {
310  if (pShape)
311  rWrapThrough = pShape->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH;
312 }
313 
315  sal_uInt16 nType)
316 {
317  if (!isTextBox(pFormat, nType))
318  return nullptr;
319  return pFormat->GetOtherTextBoxFormat();
320 }
321 
322 SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XShape> const& xShape)
323 {
324  auto pShape = dynamic_cast<SwXShape*>(xShape.get());
325  if (!pShape)
326  return nullptr;
327 
328  SwFrameFormat* pFormat = pShape->GetFrameFormat();
329  return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT);
330 }
331 
332 uno::Reference<text::XTextFrame>
333 SwTextBoxHelper::getUnoTextFrame(uno::Reference<drawing::XShape> const& xShape)
334 {
335  if (xShape)
336  {
337  auto pFrameFormat = SwTextBoxHelper::getOtherTextBoxFormat(xShape);
338  if (pFrameFormat)
339  {
340  auto pSdrObj = pFrameFormat->FindSdrObject();
341  if (pSdrObj && pSdrObj->IsTextBox())
342  {
343  return uno::Reference<css::text::XTextFrame>(pSdrObj->getUnoShape(),
344  uno::UNO_QUERY);
345  }
346  }
347  }
348  return uno::Reference<css::text::XTextFrame>();
349 }
350 
351 template <typename T> static void lcl_queryInterface(const SwFrameFormat* pShape, uno::Any& rAny)
352 {
354  {
355  uno::Reference<T> const xInterface(
356  SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
357  rAny <<= xInterface;
358  }
359 }
360 
362 {
363  uno::Any aRet;
364 
366  {
367  lcl_queryInterface<text::XTextAppend>(pShape, aRet);
368  }
369  else if (rType == cppu::UnoType<css::text::XText>::get())
370  {
371  lcl_queryInterface<text::XText>(pShape, aRet);
372  }
373  else if (rType == cppu::UnoType<css::text::XTextRange>::get())
374  {
375  lcl_queryInterface<text::XTextRange>(pShape, aRet);
376  }
377 
378  return aRet;
379 }
380 
382 {
383  tools::Rectangle aRet;
384  aRet.SetEmpty();
385  auto pSdrShape = pShape->FindRealSdrObject();
386  auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(pSdrShape);
387  if (pCustomShape)
388  {
389  // Need to temporarily release the lock acquired in
390  // SdXMLShapeContext::AddShape(), otherwise we get an empty rectangle,
391  // see EnhancedCustomShapeEngine::getTextBounds().
392  uno::Reference<document::XActionLockable> xLockable(pCustomShape->getUnoShape(),
393  uno::UNO_QUERY);
394  sal_Int16 nLocks = 0;
395  if (xLockable.is())
396  nLocks = xLockable->resetActionLocks();
397  pCustomShape->GetTextBounds(aRet);
398  if (nLocks)
399  xLockable->setActionLocks(nLocks);
400  }
401  else if (pSdrShape)
402  {
403  // fallback - get *any* bound rect we can possibly get hold of
404  aRet = pSdrShape->GetCurrentBoundRect();
405  }
406 
407  if (!bAbsolute && pSdrShape)
408  {
409  // Relative, so count the logic (reference) rectangle, see the EnhancedCustomShape2d ctor.
410  Point aPoint(pSdrShape->GetSnapRect().Center());
411  Size aSize(pSdrShape->GetLogicRect().GetSize());
412  aPoint.AdjustX(-(aSize.Width() / 2));
413  aPoint.AdjustY(-(aSize.Height() / 2));
414  tools::Rectangle aLogicRect(aPoint, aSize);
415  aRet.Move(-1 * aLogicRect.Left(), -1 * aLogicRect.Top());
416  }
417 
418  return aRet;
419 }
420 
421 void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, std::u16string_view rPropertyName,
422  const css::uno::Any& rValue)
423 {
424  // Textframes does not have valid horizontal adjust property, so map it to paragraph adjust property
425  if (rPropertyName == UNO_NAME_TEXT_HORZADJUST)
426  {
427  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
428  if (!pFormat)
429  return;
430 
431  auto xTextFrame = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
432  uno::Reference<text::XTextCursor> xCursor = xTextFrame->getText()->createTextCursor();
433 
434  // Select all paragraphs in the textframe
435  xCursor->gotoStart(false);
436  xCursor->gotoEnd(true);
437  uno::Reference<beans::XPropertySet> xFrameParaProps(xCursor, uno::UNO_QUERY);
438 
439  // And simply map the property
440  const auto eValue = rValue.get<drawing::TextHorizontalAdjust>();
441  switch (eValue)
442  {
443  case drawing::TextHorizontalAdjust::TextHorizontalAdjust_CENTER:
444  xFrameParaProps->setPropertyValue(
446  uno::makeAny(style::ParagraphAdjust::ParagraphAdjust_CENTER)); //3
447  break;
448  case drawing::TextHorizontalAdjust::TextHorizontalAdjust_LEFT:
449  xFrameParaProps->setPropertyValue(
451  uno::makeAny(style::ParagraphAdjust::ParagraphAdjust_LEFT)); //0
452  break;
453  case drawing::TextHorizontalAdjust::TextHorizontalAdjust_RIGHT:
454  xFrameParaProps->setPropertyValue(
456  uno::makeAny(style::ParagraphAdjust::ParagraphAdjust_RIGHT)); //1
457  break;
458  default:
459  SAL_WARN("sw.core",
460  "SwTextBoxHelper::syncProperty: unhandled TextHorizontalAdjust: "
461  << static_cast<sal_Int32>(eValue));
462  break;
463  }
464  return;
465  }
466 
467  if (rPropertyName == u"CustomShapeGeometry")
468  {
469  // CustomShapeGeometry changes the textbox position offset and size, so adjust both.
470  syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::Any());
471 
472  SdrObject* pObject = pShape->FindRealSdrObject();
473  if (pObject)
474  {
475  tools::Rectangle aRectangle(pObject->GetSnapRect());
476  syncProperty(
478  uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Left()))));
479  syncProperty(
481  uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top()))));
482  }
483 
484  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
485  if (!pFormat)
486  return;
487 
488  comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue);
489  auto it = aCustomShapeGeometry.find("TextPreRotateAngle");
490  if (it == aCustomShapeGeometry.end())
491  {
492  it = aCustomShapeGeometry.find("TextRotateAngle");
493  }
494 
495  if (it != aCustomShapeGeometry.end())
496  {
497  auto nAngle = it->second.has<sal_Int32>() ? it->second.get<sal_Int32>() : 0;
498  if (nAngle == 0)
499  {
500  nAngle = it->second.has<double>() ? it->second.get<double>() : 0;
501  }
502 
503  sal_Int16 nDirection = 0;
504  switch (nAngle)
505  {
506  case -90:
507  nDirection = text::WritingMode2::TB_RL;
508  break;
509  case -270:
510  nDirection = text::WritingMode2::BT_LR;
511  break;
512  default:
513  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled property value: "
514  "CustomShapeGeometry:TextPreRotateAngle: "
515  << nAngle);
516  break;
517  }
518 
519  if (nDirection)
520  {
521  syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(nDirection));
522  }
523  }
524  }
525  else if (rPropertyName == UNO_NAME_TEXT_VERT_ADJUST)
526  syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0, rValue);
527  else if (rPropertyName == UNO_NAME_TEXT_AUTOGROWHEIGHT)
528  syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, rValue);
529  else if (rPropertyName == UNO_NAME_TEXT_LEFTDIST)
530  syncProperty(pShape, RES_BOX, LEFT_BORDER_DISTANCE, rValue);
531  else if (rPropertyName == UNO_NAME_TEXT_RIGHTDIST)
532  syncProperty(pShape, RES_BOX, RIGHT_BORDER_DISTANCE, rValue);
533  else if (rPropertyName == UNO_NAME_TEXT_UPPERDIST)
534  syncProperty(pShape, RES_BOX, TOP_BORDER_DISTANCE, rValue);
535  else if (rPropertyName == UNO_NAME_TEXT_LOWERDIST)
536  syncProperty(pShape, RES_BOX, BOTTOM_BORDER_DISTANCE, rValue);
537  else if (rPropertyName == UNO_NAME_TEXT_WRITINGMODE)
538  {
539  text::WritingMode eMode;
540  sal_Int16 eMode2;
541  if (rValue >>= eMode)
542  syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)));
543  else if (rValue >>= eMode2)
544  syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(eMode2));
545  }
546  else
547  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled property: "
548  << static_cast<OUString>(rPropertyName));
549 }
550 
551 void SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
552  css::uno::Any& rValue)
553 {
554  if (!pShape)
555  return;
556 
557  nMemberID &= ~CONVERT_TWIPS;
558 
559  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
560  if (!pFormat)
561  return;
562 
563  if (nWID != RES_CHAIN)
564  return;
565 
566  switch (nMemberID)
567  {
568  case MID_CHAIN_PREVNAME:
569  case MID_CHAIN_NEXTNAME:
570  {
571  const SwFormatChain& rChain = pFormat->GetChain();
572  rChain.QueryValue(rValue, nMemberID);
573  }
574  break;
575  case MID_CHAIN_NAME:
576  rValue <<= pFormat->GetName();
577  break;
578  default:
579  SAL_WARN("sw.core", "SwTextBoxHelper::getProperty: unhandled member-id: "
580  << static_cast<sal_uInt16>(nMemberID));
581  break;
582  }
583 }
584 
585 css::uno::Any SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, OUString sPropName)
586 {
587  if (!pShape)
588  return uno::Any();
589 
590  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
591  if (!pFormat)
592  return uno::Any();
593 
594  uno::Reference<beans::XPropertySet> const xPropertySet(
595  SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
596 
597  return xPropertySet->getPropertyValue(sPropName);
598 }
599 
600 void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
601  const css::uno::Any& rValue)
602 {
603  // No shape yet? Then nothing to do, initial properties are set by create().
604  if (!pShape)
605  return;
606 
607  uno::Any aValue(rValue);
608  nMemberID &= ~CONVERT_TWIPS;
609 
610  SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT);
611  if (!pFormat)
612  return;
613 
614  OUString aPropertyName;
615  bool bAdjustX = false;
616  bool bAdjustY = false;
617  bool bAdjustSize = false;
618  switch (nWID)
619  {
620  case RES_HORI_ORIENT:
621  switch (nMemberID)
622  {
624  aPropertyName = UNO_NAME_HORI_ORIENT;
625  break;
627  aPropertyName = UNO_NAME_HORI_ORIENT_RELATION;
628  break;
630  aPropertyName = UNO_NAME_HORI_ORIENT_POSITION;
631  bAdjustX = true;
632  break;
633  default:
634  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
635  << static_cast<sal_uInt16>(nMemberID)
636  << " (which-id: " << nWID << ")");
637  break;
638  }
639  break;
640  case RES_LR_SPACE:
641  {
642  switch (nMemberID)
643  {
644  case MID_L_MARGIN:
645  aPropertyName = UNO_NAME_LEFT_MARGIN;
646  break;
647  case MID_R_MARGIN:
648  aPropertyName = UNO_NAME_RIGHT_MARGIN;
649  break;
650  default:
651  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
652  << static_cast<sal_uInt16>(nMemberID)
653  << " (which-id: " << nWID << ")");
654  break;
655  }
656  break;
657  }
658  case RES_VERT_ORIENT:
659  switch (nMemberID)
660  {
662  aPropertyName = UNO_NAME_VERT_ORIENT;
663  break;
665  aPropertyName = UNO_NAME_VERT_ORIENT_RELATION;
666  break;
668  aPropertyName = UNO_NAME_VERT_ORIENT_POSITION;
669  bAdjustY = true;
670  break;
671  default:
672  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
673  << static_cast<sal_uInt16>(nMemberID)
674  << " (which-id: " << nWID << ")");
675  break;
676  }
677  break;
678  case RES_FRM_SIZE:
679  switch (nMemberID)
680  {
682  aPropertyName = UNO_NAME_WIDTH_TYPE;
683  break;
685  aPropertyName = UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT;
686  break;
688  aPropertyName = UNO_NAME_RELATIVE_HEIGHT_RELATION;
689  break;
691  aPropertyName = UNO_NAME_RELATIVE_WIDTH_RELATION;
692  break;
693  default:
694  aPropertyName = UNO_NAME_SIZE;
695  bAdjustSize = true;
696  break;
697  }
698  break;
699  case RES_ANCHOR:
700  switch (nMemberID)
701  {
703  {
704  uno::Reference<beans::XPropertySet> const xPropertySet(
705  SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat),
706  uno::UNO_QUERY);
707  // Surround (Wrap) has to be THROUGH always:
708  xPropertySet->setPropertyValue(UNO_NAME_SURROUND,
709  uno::makeAny(text::WrapTextMode_THROUGH));
710  // Use At_Char anchor instead of As_Char anchoring:
711  if (aValue.get<text::TextContentAnchorType>()
712  == text::TextContentAnchorType::TextContentAnchorType_AS_CHARACTER)
713  {
714  xPropertySet->setPropertyValue(
716  uno::makeAny(
717  text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH));
718  }
719  else // Otherwise copy the anchor type of the shape
720  {
721  xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
722  }
723  // After anchoring the position must be set as well:
724  // At-Page anchor this will be the following:
725  if (aValue.get<text::TextContentAnchorType>()
726  == text::TextContentAnchorType::TextContentAnchorType_AT_PAGE)
727  {
728  xPropertySet->setPropertyValue(
730  uno::makeAny(pShape->GetAnchor().GetPageNum()));
731  }
732  // At-Content Anchors have to be synced:
733  if (aValue.get<text::TextContentAnchorType>()
734  == text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH
735  || aValue.get<text::TextContentAnchorType>()
736  == text::TextContentAnchorType::TextContentAnchorType_AT_CHARACTER)
737  {
738  // If the shape has content...
739  if (auto aPos = pShape->GetAnchor().GetContentAnchor())
740  {
741  SwFormatAnchor aAnch(pFormat->GetAnchor());
742  // ...set it for the textframe too.
743  aAnch.SetAnchor(aPos);
744  pFormat->SetFormatAttr(aAnch);
745  }
746  else
747  SAL_WARN("sw.core",
748  "SwTextBoxHelper::syncProperty: Anchor without content!");
749  }
750  // And the repositioning:
751  tools::Rectangle aRect(getTextRectangle(pShape, false));
752 
753  SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
754  aNewHOri.SetPos(aNewHOri.GetPos() + aRect.getX());
755  SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
756  aNewVOri.SetPos(aNewVOri.GetPos() + aRect.getY());
757 
758  pFormat->SetFormatAttr(aNewHOri);
759  pFormat->SetFormatAttr(aNewVOri);
760  return;
761  }
762  break;
763  default:
764  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
765  << static_cast<sal_uInt16>(nMemberID)
766  << " (which-id: " << nWID << ")");
767  break;
768  }
769  break;
770  case FN_TEXT_RANGE:
771  {
772  uno::Reference<text::XTextRange> xRange;
773  rValue >>= xRange;
774  SwUnoInternalPaM aInternalPaM(*pFormat->GetDoc());
775  if (sw::XTextRangeToSwPaM(aInternalPaM, xRange))
776  {
777  SwFormatAnchor aAnchor(pFormat->GetAnchor());
778  aAnchor.SetAnchor(aInternalPaM.Start());
779  pFormat->SetFormatAttr(aAnchor);
780  }
781  }
782  break;
783  case RES_CHAIN:
784  switch (nMemberID)
785  {
786  case MID_CHAIN_PREVNAME:
787  aPropertyName = UNO_NAME_CHAIN_PREV_NAME;
788  break;
789  case MID_CHAIN_NEXTNAME:
790  aPropertyName = UNO_NAME_CHAIN_NEXT_NAME;
791  break;
792  default:
793  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
794  << static_cast<sal_uInt16>(nMemberID)
795  << " (which-id: " << nWID << ")");
796  break;
797  }
798  break;
800  aPropertyName = UNO_NAME_TEXT_VERT_ADJUST;
801  break;
802  case RES_BOX:
803  switch (nMemberID)
804  {
806  aPropertyName = UNO_NAME_LEFT_BORDER_DISTANCE;
807  break;
809  aPropertyName = UNO_NAME_RIGHT_BORDER_DISTANCE;
810  break;
811  case TOP_BORDER_DISTANCE:
812  aPropertyName = UNO_NAME_TOP_BORDER_DISTANCE;
813  break;
815  aPropertyName = UNO_NAME_BOTTOM_BORDER_DISTANCE;
816  break;
817  default:
818  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
819  << static_cast<sal_uInt16>(nMemberID)
820  << " (which-id: " << nWID << ")");
821  break;
822  }
823  break;
824  case RES_OPAQUE:
825  aPropertyName = UNO_NAME_OPAQUE;
826  break;
827  case RES_FRAMEDIR:
828  aPropertyName = UNO_NAME_WRITING_MODE;
829  break;
831  switch (nMemberID)
832  {
833  case MID_ALLOW_OVERLAP:
834  aPropertyName = UNO_NAME_ALLOW_OVERLAP;
835  break;
836  default:
837  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
838  << static_cast<sal_uInt16>(nMemberID)
839  << " (which-id: " << nWID << ")");
840  break;
841  }
842  break;
843  default:
844  SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled which-id: "
845  << nWID << " (member-id: " << static_cast<sal_uInt16>(nMemberID)
846  << ")");
847  break;
848  }
849 
850  if (aPropertyName.isEmpty())
851  return;
852 
853  // Position/size should be the text position/size, not the shape one as-is.
854  if (bAdjustX || bAdjustY || bAdjustSize)
855  {
856  tools::Rectangle aRect = getTextRectangle(pShape, /*bAbsolute=*/false);
857  if (!aRect.IsEmpty())
858  {
859  if (bAdjustX || bAdjustY)
860  {
861  sal_Int32 nValue;
862  if (aValue >>= nValue)
863  {
864  if (bAdjustX)
865  nValue += convertTwipToMm100(aRect.getX());
866  else if (bAdjustY)
867  nValue += convertTwipToMm100(aRect.getY());
868  aValue <<= nValue;
869  }
870  }
871  else if (bAdjustSize)
872  {
873  awt::Size aSize(convertTwipToMm100(aRect.getWidth()),
874  convertTwipToMm100(aRect.getHeight()));
875  aValue <<= aSize;
876  }
877  }
878  }
879 
880  uno::Reference<beans::XPropertySet> const xPropertySet(
881  SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
882  xPropertySet->setPropertyValue(aPropertyName, aValue);
883 }
884 
886  std::map<const SwFrameFormat*, const SwFrameFormat*>& rLinks)
887 {
888  for (const auto pFormat : rFormats)
889  {
890  if (SwFrameFormat* pTextBox = getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
891  rLinks[pFormat] = pTextBox;
892  }
893 }
894 
895 void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrameFormat*>& rNew,
896  SavedLink& rSavedLinks)
897 {
898  std::size_t i = 0;
899  for (const auto& rIt : rOld)
900  {
901  auto aTextBoxIt = rSavedLinks.find(rIt.GetFormat());
902  if (aTextBoxIt != rSavedLinks.end())
903  {
904  std::size_t j = 0;
905  for (const auto& rJt : rOld)
906  {
907  if (rJt.GetFormat() == aTextBoxIt->second)
908  rNew[i]->SetFormatAttr(rNew[j]->GetContent());
909  ++j;
910  }
911  }
912  ++i;
913  }
914 }
915 
916 text::TextContentAnchorType SwTextBoxHelper::mapAnchorType(const RndStdIds& rAnchorID)
917 {
918  text::TextContentAnchorType aAnchorType;
919  switch (rAnchorID)
920  {
921  case RndStdIds::FLY_AS_CHAR:
922  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AS_CHARACTER;
923  break;
924  case RndStdIds::FLY_AT_CHAR:
925  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_CHARACTER;
926  break;
927  case RndStdIds::FLY_AT_PARA:
928  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH;
929  break;
930  case RndStdIds::FLY_AT_PAGE:
931  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PAGE;
932  break;
933  case RndStdIds::FLY_AT_FLY:
934  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_FRAME;
935  break;
936  default:
937  aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH;
938  SAL_WARN("sw.core", "SwTextBoxHelper::mapAnchorType: Unknown AnchorType!");
939  break;
940  }
941  return aAnchorType;
942 }
943 
945 {
946  SwFrameFormat* pFormat = getOtherTextBoxFormat(&rShape, RES_DRAWFRMFMT);
947  if (!pFormat)
948  return;
949 
950  SfxItemSet aTextBoxSet(pFormat->GetDoc()->GetAttrPool(), aFrameFormatSetRange);
951 
952  SfxItemIter aIter(rSet);
953  const SfxPoolItem* pItem = aIter.GetCurItem();
954 
955  do
956  {
957  switch (pItem->Which())
958  {
959  case RES_VERT_ORIENT:
960  {
961  // The new position can be with anchor changing so sync it!
962  const text::TextContentAnchorType aNewAnchorType
963  = mapAnchorType(rShape.GetAnchor().GetAnchorId());
964  syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType));
965  auto& rOrient = static_cast<const SwFormatVertOrient&>(*pItem);
966  SwFormatVertOrient aOrient(rOrient);
967 
968  tools::Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
969  if (!aRect.IsEmpty())
970  aOrient.SetPos(aOrient.GetPos() + aRect.getY());
971 
972  if (rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
973  && rShape.GetAnchor().GetPageNum() != 0)
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  auto& rOrient = static_cast<const SwFormatHoriOrient&>(*pItem);
993  SwFormatHoriOrient aOrient(rOrient);
994 
995  tools::Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
996  if (!aRect.IsEmpty())
997  aOrient.SetPos(aOrient.GetPos() + aRect.getX());
998 
999  if (rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
1000  && rShape.GetAnchor().GetPageNum() != 0)
1002  aTextBoxSet.Put(aOrient);
1003  }
1004  break;
1005  case RES_FRM_SIZE:
1006  {
1007  // In case the shape got resized, then we need to adjust both
1008  // the position and the size of the textbox (e.g. larger
1009  // rounded edges of a rectangle -> need to push right/down the
1010  // textbox).
1011  SwFormatVertOrient aVertOrient(rShape.GetVertOrient());
1012  SwFormatHoriOrient aHoriOrient(rShape.GetHoriOrient());
1013  SwFormatFrameSize aSize(pFormat->GetFrameSize());
1014 
1015  tools::Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
1016  if (!aRect.IsEmpty())
1017  {
1018  aVertOrient.SetPos(aVertOrient.GetPos() + aRect.getY());
1019  aTextBoxSet.Put(aVertOrient);
1020 
1021  aHoriOrient.SetPos(aHoriOrient.GetPos() + aRect.getX());
1022  aTextBoxSet.Put(aHoriOrient);
1023 
1024  aSize.SetWidth(aRect.getWidth());
1025  aSize.SetHeight(aRect.getHeight());
1026  aTextBoxSet.Put(aSize);
1027  }
1028  }
1029  break;
1030  case RES_ANCHOR:
1031  {
1032  auto& rAnchor = static_cast<const SwFormatAnchor&>(*pItem);
1033  if (rAnchor == rShape.GetAnchor())
1034  // the anchor have to be synced
1035  {
1036  const text::TextContentAnchorType aNewAnchorType
1037  = mapAnchorType(rShape.GetAnchor().GetAnchorId());
1038  syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE,
1039  uno::Any(aNewAnchorType));
1040  }
1041  else
1042  {
1043  SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrameAttr: The anchor of the "
1044  "shape different from the textframe!");
1045  }
1046  }
1047  break;
1048  default:
1049  SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrameAttr: unhandled which-id: "
1050  << pItem->Which());
1051  break;
1052  }
1053 
1054  pItem = aIter.NextItem();
1055  } while (pItem && (0 != pItem->Which()));
1056 
1057  if (aTextBoxSet.Count())
1058  pFormat->GetDoc()->SetFlyFrameAttr(*pFormat, aTextBoxSet);
1059 }
1060 
1062 {
1063  if (!pObj)
1064  return;
1065  uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY);
1066  if (!xShape)
1067  return;
1068  uno::Reference<beans::XPropertySet> const xPropertySet(xShape, uno::UNO_QUERY);
1069 
1070  auto pParentFormat = getOtherTextBoxFormat(getOtherTextBoxFormat(xShape), RES_FLYFRMFMT);
1071  if (!pParentFormat)
1072  return;
1073 
1074  // Sync the padding
1075  syncProperty(pParentFormat, UNO_NAME_TEXT_LEFTDIST,
1076  xPropertySet->getPropertyValue(UNO_NAME_TEXT_LEFTDIST));
1077  syncProperty(pParentFormat, UNO_NAME_TEXT_RIGHTDIST,
1078  xPropertySet->getPropertyValue(UNO_NAME_TEXT_RIGHTDIST));
1079  syncProperty(pParentFormat, UNO_NAME_TEXT_UPPERDIST,
1080  xPropertySet->getPropertyValue(UNO_NAME_TEXT_UPPERDIST));
1081  syncProperty(pParentFormat, UNO_NAME_TEXT_LOWERDIST,
1082  xPropertySet->getPropertyValue(UNO_NAME_TEXT_LOWERDIST));
1083 
1084  // Sync the text aligning
1085  syncProperty(pParentFormat, UNO_NAME_TEXT_VERTADJUST,
1086  xPropertySet->getPropertyValue(UNO_NAME_TEXT_VERTADJUST));
1087  syncProperty(pParentFormat, UNO_NAME_TEXT_HORZADJUST,
1088  xPropertySet->getPropertyValue(UNO_NAME_TEXT_HORZADJUST));
1089 
1090  // tdf137803: Sync autogrow:
1091  const bool bIsAutoGrow
1092  = xPropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT).get<bool>();
1093  const bool bIsAutoWrap = xPropertySet->getPropertyValue(UNO_NAME_TEXT_WORDWRAP).get<bool>();
1094 
1095  syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, uno::Any(bIsAutoGrow));
1096 
1097  syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_WIDTH_TYPE,
1098  uno::Any(bIsAutoWrap ? text::SizeType::FIX : text::SizeType::MIN));
1099 }
1100 
1101 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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 css::uno::Any getByIndex(SdrPage const *pPage, sal_Int32 nIndex)
Get a shape by index, excluding TextBoxes.
void SetHeight(tools::Long n)
#define UNO_NAME_HORI_ORIENT_POSITION
Definition: unoprnms.hxx:264
#define UNO_NAME_TEXT_RIGHTDIST
SwDocShell * GetDocShell()
Definition: doc.hxx:1354
#define UNO_NAME_BOTTOM_BORDER
Definition: unoprnms.hxx:357
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:190
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
Definition: atrfrm.cxx:2056
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:106
#define UNO_NAME_IS_FOLLOWING_TEXT_FLOW
Definition: unoprnms.hxx:740
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
static void destroy(SwFrameFormat *pShape)
Destroy a TextBox for a shape.
#define UNO_NAME_ALLOW_OVERLAP
Definition: unoprnms.hxx:866
constexpr TypedWhichId< SdrTextVertAdjustItem > RES_TEXT_VERT_ADJUST(130)
sal_uInt16 GetPageNum() const
Definition: fmtanchr.hxx:66
SwTwips GetPos() const
Definition: fmtornt.hxx:92
virtual void SetModified()=0
Must be called manually at changes of format.
#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
Definition: doc.hxx:187
virtual bool IsTextBox() const
size_t GetObjCount() const
OUString GetUniqueFrameName() const
Definition: doclay.cxx:1377
tools::Long getY() const
#define RIGHT_BORDER_DISTANCE
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:227
#define UNO_NAME_VERT_ORIENT
Definition: unoprnms.hxx:329
#define UNO_NAME_TEXT_UPPERDIST
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:55
EmbeddedObjectRef * pObject
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType)
If we have an associated TextFrame, then return that.
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:744
std::map< const SwFrameFormat *, const SwFrameFormat * > SavedLink
Maps a draw format to a fly format.
static css::uno::Any queryInterface(const SwFrameFormat *pShape, const css::uno::Type &rType)
Get interface of a shape's TextBox, if there is any.
virtual const tools::Rectangle & GetSnapRect() const
constexpr auto convertTwipToMm100(N n)
bool IsEmpty() const
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:188
#define UNO_NAME_CHAIN_NEXT_NAME
Definition: unoprnms.hxx:231
virtual css::uno::Reference< css::uno::XInterface > getUnoShape()
#define MID_FRMSIZE_SIZE
Definition: unomid.h:70
tools::Long Left() const
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(103)
SdrPage * getSdrPageFromSdrObject() const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
#define MID_FOLLOW_TEXT_FLOW
Definition: unomid.h:152
void SetOtherTextBoxFormat(SwFrameFormat *pFormat)
Definition: atrfrm.cxx:2493
const OUString & GetName() const
Definition: format.hxx:115
int nCount
#define UNO_NAME_SIZE
Definition: unoprnms.hxx:303
virtual void DelLayoutFormat(SwFrameFormat *pFormat)=0
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType)
Is the frame format a text box?
Mode eMode
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
#define UNO_NAME_VERT_ORIENT_RELATION
Definition: unoprnms.hxx:332
tools::Long getX() const
#define UNO_NAME_TEXT_WRITINGMODE
#define FN_TEXT_RANGE
Definition: cmdid.h:807
css::uno::Reference< css::frame::XModel > GetBaseModel() const
constexpr TypedWhichId< SwFormatWrapInfluenceOnObjPos > RES_WRAP_INFLUENCE_ON_OBJPOS(125)
Specific frame formats (frames, DrawObjects).
#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:260
#define MID_CHAIN_NEXTNAME
Definition: unomid.h:57
#define MID_L_MARGIN
static void create(SwFrameFormat *pShape, bool bCopyText=false)
Create a TextBox for a shape.
#define MID_ANCHOR_ANCHORTYPE
Definition: unomid.h:43
Style of a layout element.
Definition: frmfmt.hxx:58
#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
#define UNO_NAME_RIGHT_BORDER
Definition: unoprnms.hxx:355
#define MID_FRMSIZE_WIDTH_TYPE
Definition: unomid.h:86
#define UNO_NAME_FILL_TRANSPARENCE
SwFrameFormat * GetOtherTextBoxFormat() const
Definition: frmfmt.hxx:102
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:170
#define MID_VERTORIENT_POSITION
Definition: unomid.h:36
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:60
FlyAnchors.
Definition: fmtanchr.hxx:34
void SetRelationOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:90
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.
sal_uInt32 GetOrdNum() const
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:394
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
#define UNO_NAME_LEFT_BORDER
Definition: unoprnms.hxx:354
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
tools::Long Top() const
#define UNO_NAME_LEFT_BORDER_DISTANCE
Definition: unoprnms.hxx:359
#define UNO_NAME_CHAIN_PREV_NAME
Definition: unoprnms.hxx:232
bool SetFlyFrameAttr(SwFrameFormat &rFlyFormat, SfxItemSet &rSet)
Definition: docfly.cxx:557
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
constexpr TypedWhichId< SwFormatContent > RES_CNTNT(95)
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange,::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1100
#define UNO_NAME_RIGHT_MARGIN
Definition: unoprnms.hxx:68
#define UNO_NAME_TOP_BORDER
Definition: unoprnms.hxx:356
sal_uInt16 const aFrameFormatSetRange[]
Definition: init.cxx:233
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:449
#define UNO_NAME_TOP_BORDER_DISTANCE
Definition: unoprnms.hxx:361
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
#define UNO_NAME_TEXT_VERT_ADJUST
Definition: unoprnms.hxx:855
#define UNO_NAME_SURROUND
Definition: unoprnms.hxx:310
#define MID_HORIORIENT_ORIENT
Definition: unomid.h:38
#define MID_FRMSIZE_REL_HEIGHT_RELATION
Definition: unomid.h:88
virtual bool ResetFormatAttr(sal_uInt16 nWhich1, sal_uInt16 nWhich2=0)
Definition: format.cxx:623
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:67
#define MID_VERTORIENT_ORIENT
Definition: unomid.h:34
unsigned char sal_uInt8
#define UNO_NAME_BOTTOM_BORDER_DISTANCE
Definition: unoprnms.hxx:362
#define UNO_NAME_ANCHOR_TYPE
Definition: unoprnms.hxx:225
SwTwips GetPos() const
Definition: fmtornt.hxx:59
#define UNO_NAME_TEXT_LEFTDIST
#define MID_FRMSIZE_REL_WIDTH_RELATION
Definition: unomid.h:87
#define UNO_NAME_HORI_ORIENT_RELATION
Definition: unoprnms.hxx:263
static SW_DLLPUBLIC css::uno::Reference< css::text::XTextFrame > CreateXTextFrame(SwDoc &rDoc, SwFrameFormat *pFrameFormat)
Definition: unoframe.cxx:3193
#define TOP_BORDER_DISTANCE
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
#define UNO_NAME_TEXT_AUTOGROWHEIGHT
void * p
static css::uno::Reference< css::uno::XInterface > MakeInstance(SwServiceType nObjectType, SwDoc &rDoc)
Definition: unocoll.cxx:512
bool GetTextBounds(tools::Rectangle &rTextBound) const
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
static tools::Rectangle getTextRectangle(SwFrameFormat *pShape, bool bAbsolute=true)
Return the textbox rectangle of a draw shape (in twips).
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(157)
void SetRelationOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:57
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
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
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
static void syncFlyFrameAttr(SwFrameFormat &rShape, SfxItemSet const &rSet)
Similar to syncProperty(), but used by the internal API (e.g. for UI purposes).
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
#define SAL_WARN(area, stream)
static void syncProperty(SwFrameFormat *pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, const css::uno::Any &rValue)
Sync property of TextBox with the one of the shape.
RndStdIds
#define UNO_NAME_SIZE_TYPE
Definition: unoprnms.hxx:258
#define UNO_NAME_RIGHT_BORDER_DISTANCE
Definition: unoprnms.hxx:360
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:120
#define UNO_NAME_WIDTH_TYPE
Definition: unoprnms.hxx:741
#define UNO_NAME_VERT_ORIENT_POSITION
Definition: unoprnms.hxx:331
constexpr TypedWhichId< SwFormatFollowTextFlow > RES_FOLLOW_TEXT_FLOW(123)
#define UNO_NAME_OPAQUE
Definition: unoprnms.hxx:282
sal_uInt16 Which() const
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2712
constexpr TypedWhichId< SwFormatAnchor > RES_ANCHOR(104)
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1321
sal_Int16 nValue
#define MID_ALLOW_OVERLAP
Definition: unomid.h:149
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1493
#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.
#define UNO_NAME_TEXT_VERTADJUST