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 <fmtfollowtextflow.hxx>
30#include <frmfmt.hxx>
31#include <frameformats.hxx>
32#include <dflyobj.hxx>
33#include <swtable.hxx>
34
35#include <editeng/unoprnms.hxx>
36#include <editeng/memberids.h>
37#include <svx/svdoashp.hxx>
38#include <svx/svdpage.hxx>
39#include <svl/itemiter.hxx>
41#include <sal/log.hxx>
43#include <svx/swframetypes.hxx>
44#include <drawdoc.hxx>
45#include <IDocumentUndoRedo.hxx>
47#include <frmatr.hxx>
48
49#include <com/sun/star/document/XActionLockable.hpp>
50#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
51#include <com/sun/star/text/SizeType.hpp>
52#include <com/sun/star/text/WrapTextMode.hpp>
53#include <com/sun/star/text/XTextDocument.hpp>
54#include <com/sun/star/text/XTextFrame.hpp>
55#include <com/sun/star/table/BorderLine2.hpp>
56#include <com/sun/star/text/WritingMode.hpp>
57#include <com/sun/star/text/WritingMode2.hpp>
58#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
59#include <com/sun/star/style/ParagraphAdjust.hpp>
60
61using namespace com::sun::star;
62
63void SwTextBoxHelper::create(SwFrameFormat* pShape, SdrObject* pObject, bool bCopyText)
64{
65 assert(pShape);
66 assert(pObject);
67
68 // If TextBox wasn't enabled previously
69 if (pShape->GetOtherTextBoxFormats() && pShape->GetOtherTextBoxFormats()->GetTextBox(pObject))
70 return;
71
72 // Store the current text content of the shape
73 OUString sCopyableText;
74
75 if (bCopyText)
76 {
77 if (pObject)
78 {
79 uno::Reference<text::XText> xSrcCnt(pObject->getWeakUnoShape().get(), uno::UNO_QUERY);
80 auto xCur = xSrcCnt->createTextCursor();
81 xCur->gotoStart(false);
82 xCur->gotoEnd(true);
83 sCopyableText = xCur->getText()->getString();
84 }
85 }
86
87 // Create the associated TextFrame and insert it into the document.
88 uno::Reference<text::XTextContent> xTextFrame(
90 uno::UNO_QUERY);
91 uno::Reference<text::XTextDocument> xTextDocument(
92 pShape->GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
93 uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(),
94 uno::UNO_QUERY);
95 xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>());
96
97 // Link FLY and DRAW formats, so it becomes a text box (needed for syncProperty calls).
98 uno::Reference<text::XTextFrame> xRealTextFrame(xTextFrame, uno::UNO_QUERY);
99 auto pTextFrame = dynamic_cast<SwXTextFrame*>(xRealTextFrame.get());
100 assert(nullptr != pTextFrame);
101 SwFrameFormat* pFormat = pTextFrame->GetFrameFormat();
102
103 assert(nullptr != dynamic_cast<SwDrawFrameFormat*>(pShape));
104 assert(nullptr != dynamic_cast<SwFlyFrameFormat*>(pFormat));
105
106 if (!pShape->GetOtherTextBoxFormats())
107 {
108 auto pTextBox = std::make_shared<SwTextBoxNode>(SwTextBoxNode(pShape));
109 pTextBox->AddTextBox(pObject, pFormat);
110 pShape->SetOtherTextBoxFormats(pTextBox);
111 pFormat->SetOtherTextBoxFormats(pTextBox);
112 }
113 else
114 {
115 auto& pTextBox = pShape->GetOtherTextBoxFormats();
116 pTextBox->AddTextBox(pObject, pFormat);
117 pFormat->SetOtherTextBoxFormats(pTextBox);
118 }
119 // Initialize properties.
120 uno::Reference<beans::XPropertySet> xPropertySet(xTextFrame, uno::UNO_QUERY);
121 uno::Any aEmptyBorder{ table::BorderLine2() };
122 xPropertySet->setPropertyValue(UNO_NAME_TOP_BORDER, aEmptyBorder);
123 xPropertySet->setPropertyValue(UNO_NAME_BOTTOM_BORDER, aEmptyBorder);
124 xPropertySet->setPropertyValue(UNO_NAME_LEFT_BORDER, aEmptyBorder);
125 xPropertySet->setPropertyValue(UNO_NAME_RIGHT_BORDER, aEmptyBorder);
126
127 xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::Any(sal_Int32(100)));
128
129 xPropertySet->setPropertyValue(UNO_NAME_SIZE_TYPE, uno::Any(text::SizeType::FIX));
130
131 xPropertySet->setPropertyValue(UNO_NAME_SURROUND, uno::Any(text::WrapTextMode_THROUGH));
132
133 uno::Reference<container::XNamed> xNamed(xTextFrame, uno::UNO_QUERY);
134 assert(!xNamed->getName().isEmpty());
135 (void)xNamed;
136
137 // Link its text range to the original shape.
138 uno::Reference<text::XTextRange> xTextBox(xTextFrame, uno::UNO_QUERY_THROW);
139 SwUnoInternalPaM aInternalPaM(*pShape->GetDoc());
140 if (sw::XTextRangeToSwPaM(aInternalPaM, xTextBox))
141 {
142 SwAttrSet aSet(pShape->GetAttrSet());
143 SwFormatContent aContent(aInternalPaM.GetPointNode().StartOfSectionNode());
144 aSet.Put(aContent);
145 pShape->SetFormatAttr(aSet);
146 }
147
149
150 // Also initialize the properties, which are not constant, but inherited from the shape's ones.
151 uno::Reference<drawing::XShape> xShape(pObject->getUnoShape(), uno::UNO_QUERY);
152 syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::Any(xShape->getSize()), pObject);
153
154 uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
156 xShapePropertySet->getPropertyValue(UNO_NAME_IS_FOLLOWING_TEXT_FLOW), pObject);
158 xShapePropertySet->getPropertyValue(UNO_NAME_ANCHOR_TYPE), pObject);
160 xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT), pObject);
162 xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_RELATION), pObject);
164 xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT), pObject);
166 xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_RELATION), pObject);
168 xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_POSITION), pObject);
170 xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_POSITION), pObject);
172 xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT), pObject);
174 xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_VERT_ADJUST), pObject);
175 text::WritingMode eMode;
176 if (xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_WRITINGMODE) >>= eMode)
177 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(sal_Int16(eMode)), pObject);
178
179 changeAnchor(pShape, pObject);
180 syncTextBoxSize(pShape, pObject);
181
182 // Check if the shape had text before and move it to the new textframe
183 if (!bCopyText || sCopyableText.isEmpty())
184 return;
185
186 if (pObject)
187 {
188 auto pSourceText = DynCastSdrTextObj(pObject);
189 uno::Reference<text::XTextRange> xDestText(xRealTextFrame, uno::UNO_QUERY);
190
191 xDestText->setString(sCopyableText);
192
193 if (pSourceText)
194 pSourceText->SetText(OUString());
195
196 pShape->GetDoc()->getIDocumentState().SetModified();
197 }
198}
199
201 uno::Reference<text::XTextFrame> xNew)
202{
203 // Do not set invalid data
204 assert(pShapeFormat && pObj && xNew);
205 // Firstly find the format of the new textbox.
206 SwFrameFormat* pFormat = nullptr;
207 if (auto pTextFrame = dynamic_cast<SwXTextFrame*>(xNew.get()))
208 pFormat = pTextFrame->GetFrameFormat();
209 if (!pFormat)
210 return;
211
212 // If there is a format, check if the shape already has a textbox assigned to.
213 if (auto& pTextBoxNode = pShapeFormat->GetOtherTextBoxFormats())
214 {
215 // If it has a texbox, destroy it.
216 if (pTextBoxNode->GetTextBox(pObj))
217 pTextBoxNode->DelTextBox(pObj, true);
218 // And set the new one.
219 pTextBoxNode->AddTextBox(pObj, pFormat);
220 pFormat->SetOtherTextBoxFormats(pTextBoxNode);
221 }
222 else
223 {
224 // If the shape do not have a texbox node and textbox,
225 // create that for the shape.
226 auto pTextBox = std::make_shared<SwTextBoxNode>(SwTextBoxNode(pShapeFormat));
227 pTextBox->AddTextBox(pObj, pFormat);
228 pShapeFormat->SetOtherTextBoxFormats(pTextBox);
229 pFormat->SetOtherTextBoxFormats(pTextBox);
230 }
231 // Initialize its properties
232 uno::Reference<beans::XPropertySet> xPropertySet(xNew, uno::UNO_QUERY);
233 uno::Any aEmptyBorder{ table::BorderLine2() };
234 xPropertySet->setPropertyValue(UNO_NAME_TOP_BORDER, aEmptyBorder);
235 xPropertySet->setPropertyValue(UNO_NAME_BOTTOM_BORDER, aEmptyBorder);
236 xPropertySet->setPropertyValue(UNO_NAME_LEFT_BORDER, aEmptyBorder);
237 xPropertySet->setPropertyValue(UNO_NAME_RIGHT_BORDER, aEmptyBorder);
238 xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::Any(sal_Int32(100)));
239 xPropertySet->setPropertyValue(UNO_NAME_SIZE_TYPE, uno::Any(text::SizeType::FIX));
240 xPropertySet->setPropertyValue(UNO_NAME_SURROUND, uno::Any(text::WrapTextMode_THROUGH));
241 // Add a new name to it
242 uno::Reference<container::XNamed> xNamed(xNew, uno::UNO_QUERY);
243 assert(!xNamed->getName().isEmpty());
244 (void)xNamed;
245 // And sync. properties.
246 uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY);
247 syncProperty(pShapeFormat, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::Any(xShape->getSize()), pObj);
248 uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
250 xShapePropertySet->getPropertyValue(UNO_NAME_ANCHOR_TYPE), pObj);
252 xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT), pObj);
254 xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_RELATION), pObj);
256 xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT), pObj);
258 xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_RELATION), pObj);
260 xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_POSITION), pObj);
262 xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_POSITION), pObj);
264 xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT), pObj);
265 drawing::TextVerticalAdjust aVertAdj = drawing::TextVerticalAdjust_CENTER;
266 if ((uno::Reference<beans::XPropertyState>(xShape, uno::UNO_QUERY_THROW))
267 ->getPropertyState(UNO_NAME_TEXT_VERT_ADJUST)
268 != beans::PropertyState::PropertyState_DEFAULT_VALUE)
269 {
270 aVertAdj = xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_VERT_ADJUST)
271 .get<drawing::TextVerticalAdjust>();
272 }
273 xPropertySet->setPropertyValue(UNO_NAME_TEXT_VERT_ADJUST, uno::Any(aVertAdj));
274 text::WritingMode eMode;
275 if (xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_WRITINGMODE) >>= eMode)
276 syncProperty(pShapeFormat, RES_FRAMEDIR, 0, uno::Any(sal_Int16(eMode)), pObj);
277
278 // Do sync for the new textframe.
279 synchronizeGroupTextBoxProperty(&changeAnchor, pShapeFormat, pObj);
281
283}
284
285void SwTextBoxHelper::destroy(const SwFrameFormat* pShape, const SdrObject* pObject)
286{
287 // If a TextBox was enabled previously
288 auto& pTextBox = pShape->GetOtherTextBoxFormats();
289 if (pTextBox)
290 {
291 // Unlink the TextBox's text range from the original shape.
292 // Delete the associated TextFrame.
293 pTextBox->DelTextBox(pObject, true);
294 }
295}
296
297bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pFormat, sal_uInt16 nType,
298 const SdrObject* pObject)
299{
300 SolarMutexGuard aGuard;
301 assert(nType == RES_FLYFRMFMT || nType == RES_DRAWFRMFMT);
302 if (!pFormat || pFormat->Which() != nType)
303 return false;
304
305 auto& pTextBox = pFormat->GetOtherTextBoxFormats();
306 if (!pTextBox)
307 return false;
308
309 if (nType == RES_DRAWFRMFMT)
310 {
311 if (pObject)
312 return pTextBox->GetTextBox(pObject);
313 if (auto pObj = pFormat->FindRealSdrObject())
314 return pTextBox->GetTextBox(pObj);
315 }
316
317 if (nType == RES_FLYFRMFMT)
318 {
319 return pTextBox->GetOwnerShape();
320 }
321
322 return false;
323}
324
326{
327 if (!pObj)
328 return false;
329
330 uno::Reference<drawing::XShape> xShape(pObj->getWeakUnoShape().get(), uno::UNO_QUERY);
331 if (!xShape)
332 return false;
334}
335
336sal_Int32 SwTextBoxHelper::getCount(SdrPage const* pPage)
337{
338 sal_Int32 nRet = 0;
339 for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
340 {
341 SdrObject* p = pPage->GetObj(i);
342 if (p && p->IsTextBox())
343 continue;
344 ++nRet;
345 }
346 return nRet;
347}
348
349sal_Int32 SwTextBoxHelper::getCount(const SwDoc& rDoc)
350{
351 sal_Int32 nRet = 0;
352 const SwFrameFormats& rSpzFrameFormats = *rDoc.GetSpzFrameFormats();
353 for (const auto pFormat : rSpzFrameFormats)
354 {
355 if (isTextBox(pFormat, RES_FLYFRMFMT))
356 ++nRet;
357 }
358 return nRet;
359}
360
361uno::Any SwTextBoxHelper::getByIndex(SdrPage const* pPage, sal_Int32 nIndex)
362{
363 if (nIndex < 0)
364 throw lang::IndexOutOfBoundsException();
365
366 SdrObject* pRet = nullptr;
367 sal_Int32 nCount = 0; // Current logical index.
368 for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
369 {
370 SdrObject* p = pPage->GetObj(i);
371 if (p && p->IsTextBox())
372 continue;
373 if (nCount == nIndex)
374 {
375 pRet = p;
376 break;
377 }
378 ++nCount;
379 }
380
381 if (!pRet)
382 throw lang::IndexOutOfBoundsException();
383
384 return uno::Any(uno::Reference<drawing::XShape>(pRet->getUnoShape(), uno::UNO_QUERY));
385}
386
387sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject)
388{
389 if (const SdrPage* pPage = pObject->getSdrPageFromSdrObject())
390 {
391 sal_Int32 nOrder = 0; // Current logical order.
392 for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
393 {
394 SdrObject* p = pPage->GetObj(i);
395 if (p && p->IsTextBox())
396 continue;
397 if (p == pObject)
398 return nOrder;
399 ++nOrder;
400 }
401 }
402
403 SAL_WARN("sw.core", "SwTextBoxHelper::getOrdNum: no page or page doesn't contain the object");
404 return pObject->GetOrdNum();
405}
406
407void SwTextBoxHelper::getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& rWrapThrough)
408{
410 if (pShape)
411 rWrapThrough = pShape->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH;
412}
413
415 sal_uInt16 nType, const SdrObject* pObject)
416{
417 SolarMutexGuard aGuard;
418 if (!isTextBox(pFormat, nType, pObject))
419 return nullptr;
420
421 if (nType == RES_DRAWFRMFMT)
422 {
423 if (pObject)
424 return pFormat->GetOtherTextBoxFormats()->GetTextBox(pObject);
425 if (pFormat->FindRealSdrObject())
426 return pFormat->GetOtherTextBoxFormats()->GetTextBox(pFormat->FindRealSdrObject());
427 return nullptr;
428 }
429 if (nType == RES_FLYFRMFMT)
430 {
431 return pFormat->GetOtherTextBoxFormats()->GetOwnerShape();
432 }
433 return nullptr;
434}
435
436SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XShape> const& xShape)
437{
438 auto pShape = dynamic_cast<SwXShape*>(xShape.get());
439 if (!pShape)
440 return nullptr;
441
442 SwFrameFormat* pFormat = pShape->GetFrameFormat();
445}
446
447uno::Reference<text::XTextFrame>
448SwTextBoxHelper::getUnoTextFrame(uno::Reference<drawing::XShape> const& xShape)
449{
450 if (xShape)
451 {
452 auto pFrameFormat = SwTextBoxHelper::getOtherTextBoxFormat(xShape);
453 if (pFrameFormat)
454 {
455 auto pSdrObj = pFrameFormat->FindSdrObject();
456 if (pSdrObj)
457 {
458 return { pSdrObj->getUnoShape(), uno::UNO_QUERY };
459 }
460 }
461 }
462 return {};
463}
464
465template <typename T>
466static void lcl_queryInterface(const SwFrameFormat* pShape, uno::Any& rAny, SdrObject* pObj)
467{
468 if (SwFrameFormat* pFormat
470 {
471 uno::Reference<T> const xInterface(
472 static_cast<cppu::OWeakObject*>(
473 SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat).get()),
474 uno::UNO_QUERY);
475 rAny <<= xInterface;
476 }
477}
478
480 SdrObject* pObj)
481{
482 uno::Any aRet;
483
485 {
486 lcl_queryInterface<text::XTextAppend>(pShape, aRet, pObj);
487 }
488 else if (rType == cppu::UnoType<css::text::XText>::get())
489 {
490 lcl_queryInterface<text::XText>(pShape, aRet, pObj);
491 }
493 {
494 lcl_queryInterface<text::XTextRange>(pShape, aRet, pObj);
495 }
496
497 return aRet;
498}
499
501{
502 tools::Rectangle aRet;
503 aRet.SetEmpty();
504
505 assert(pShape);
506
507 auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(pShape);
508 if (pCustomShape)
509 {
510 // Need to temporarily release the lock acquired in
511 // SdXMLShapeContext::AddShape(), otherwise we get an empty rectangle,
512 // see EnhancedCustomShapeEngine::getTextBounds().
513 uno::Reference<document::XActionLockable> xLockable(pCustomShape->getUnoShape(),
514 uno::UNO_QUERY);
515 sal_Int16 nLocks = 0;
516 if (xLockable.is())
517 nLocks = xLockable->resetActionLocks();
518 pCustomShape->GetTextBounds(aRet);
519 if (nLocks)
520 xLockable->setActionLocks(nLocks);
521 }
522 else if (pShape)
523 {
524 // fallback - get *any* bound rect we can possibly get hold of
525 aRet = pShape->GetCurrentBoundRect();
526 }
527
528 if (pShape)
529 {
530 // Relative, so count the logic (reference) rectangle, see the EnhancedCustomShape2d ctor.
531 Point aPoint(pShape->GetSnapRect().Center());
532 Size aSize(pShape->GetLogicRect().GetSize());
533 aPoint.AdjustX(-(aSize.Width() / 2));
534 aPoint.AdjustY(-(aSize.Height() / 2));
535 tools::Rectangle aLogicRect(aPoint, aSize);
536 aRet.Move(-1 * aLogicRect.Left(), -1 * aLogicRect.Top());
537 }
538
539 return aRet;
540}
541
542void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, std::u16string_view rPropertyName,
543 const css::uno::Any& rValue, SdrObject* pObj)
544{
545 // Textframes does not have valid horizontal adjust property, so map it to paragraph adjust property
546 if (rPropertyName == UNO_NAME_TEXT_HORZADJUST)
547 {
548 SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
549 if (!pFormat)
550 return;
551
552 auto xTextFrame = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
553 uno::Reference<text::XTextCursor> xCursor = xTextFrame->getText()->createTextCursor();
554
555 // Select all paragraphs in the textframe
556 xCursor->gotoStart(false);
557 xCursor->gotoEnd(true);
558 uno::Reference<beans::XPropertySet> xFrameParaProps(xCursor, uno::UNO_QUERY);
559
560 // And simply map the property
561 const auto eValue = rValue.get<drawing::TextHorizontalAdjust>();
562 switch (eValue)
563 {
564 case drawing::TextHorizontalAdjust::TextHorizontalAdjust_CENTER:
565 xFrameParaProps->setPropertyValue(
567 uno::Any(style::ParagraphAdjust::ParagraphAdjust_CENTER)); //3
568 break;
569 case drawing::TextHorizontalAdjust::TextHorizontalAdjust_LEFT:
570 xFrameParaProps->setPropertyValue(
572 uno::Any(style::ParagraphAdjust::ParagraphAdjust_LEFT)); //0
573 break;
574 case drawing::TextHorizontalAdjust::TextHorizontalAdjust_RIGHT:
575 xFrameParaProps->setPropertyValue(
577 uno::Any(style::ParagraphAdjust::ParagraphAdjust_RIGHT)); //1
578 break;
579 default:
580 SAL_WARN("sw.core",
581 "SwTextBoxHelper::syncProperty: unhandled TextHorizontalAdjust: "
582 << static_cast<sal_Int32>(eValue));
583 break;
584 }
585 return;
586 }
587
588 if (rPropertyName == u"CustomShapeGeometry")
589 {
590 // CustomShapeGeometry changes the textbox position offset and size, so adjust both.
592
593 SdrObject* pObject = pObj ? pObj : pShape->FindRealSdrObject();
594 if (pObject)
595 {
596 tools::Rectangle aRectangle(pObject->GetSnapRect());
598 uno::Any(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Left()))));
600 uno::Any(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top()))));
601 }
602
603 SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
604 if (!pFormat)
605 return;
606
607 // Older documents or documents in ODF strict do not have WritingMode, but have used the
608 // TextRotateAngle values -90 and -270 to emulate these text directions of frames.
609 // ToDo: Is TextPreRotateAngle needed for diagrams or can it be removed?
610 comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue);
611 auto it = aCustomShapeGeometry.find("TextPreRotateAngle");
612 if (it == aCustomShapeGeometry.end())
613 {
614 it = aCustomShapeGeometry.find("TextRotateAngle");
615 }
616
617 if (it != aCustomShapeGeometry.end())
618 {
619 auto nAngle = it->second.has<sal_Int32>() ? it->second.get<sal_Int32>() : 0;
620 if (nAngle == 0)
621 {
622 nAngle = it->second.has<double>() ? it->second.get<double>() : 0;
623 }
624
625 sal_Int16 nDirection = 0;
626 switch (nAngle)
627 {
628 case -90:
629 nDirection = text::WritingMode2::TB_RL90;
630 break;
631 case -270:
632 nDirection = text::WritingMode2::BT_LR;
633 break;
634 default:
635 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled property value: "
636 "CustomShapeGeometry:TextPreRotateAngle: "
637 << nAngle);
638 break;
639 }
640
641 if (nDirection)
642 {
643 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(nDirection), pObj);
644 }
645 }
646 }
647 else if (rPropertyName == UNO_NAME_TEXT_VERT_ADJUST)
648 syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0, rValue, pObj);
649 else if (rPropertyName == UNO_NAME_TEXT_AUTOGROWHEIGHT)
651 else if (rPropertyName == UNO_NAME_TEXT_LEFTDIST)
652 syncProperty(pShape, RES_BOX, LEFT_BORDER_DISTANCE, rValue, pObj);
653 else if (rPropertyName == UNO_NAME_TEXT_RIGHTDIST)
654 syncProperty(pShape, RES_BOX, RIGHT_BORDER_DISTANCE, rValue, pObj);
655 else if (rPropertyName == UNO_NAME_TEXT_UPPERDIST)
656 syncProperty(pShape, RES_BOX, TOP_BORDER_DISTANCE, rValue, pObj);
657 else if (rPropertyName == UNO_NAME_TEXT_LOWERDIST)
658 syncProperty(pShape, RES_BOX, BOTTOM_BORDER_DISTANCE, rValue, pObj);
659 else if (rPropertyName == UNO_NAME_TEXT_WRITINGMODE)
660 {
661 text::WritingMode eMode;
662 sal_Int16 eMode2;
663 if (rValue >>= eMode)
664 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(sal_Int16(eMode)), pObj);
665 else if (rValue >>= eMode2)
666 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(eMode2), pObj);
667 }
668 else if (rPropertyName == u"WritingMode")
669 {
670 sal_Int16 eMode2;
671 if (rValue >>= eMode2)
672 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(eMode2), pObj);
673 }
674 else
675 SAL_INFO("sw.core", "SwTextBoxHelper::syncProperty: unhandled property: "
676 << static_cast<OUString>(rPropertyName));
677}
678
679void SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
680 css::uno::Any& rValue)
681{
682 if (!pShape)
683 return;
684
685 nMemberID &= ~CONVERT_TWIPS;
686
688 if (!pFormat)
689 return;
690
691 if (nWID != RES_CHAIN)
692 return;
693
694 switch (nMemberID)
695 {
698 {
699 const SwFormatChain& rChain = pFormat->GetChain();
700 rChain.QueryValue(rValue, nMemberID);
701 }
702 break;
703 case MID_CHAIN_NAME:
704 rValue <<= pFormat->GetName();
705 break;
706 default:
707 SAL_WARN("sw.core", "SwTextBoxHelper::getProperty: unhandled member-id: "
708 << o3tl::narrowing<sal_uInt16>(nMemberID));
709 break;
710 }
711}
712
713css::uno::Any SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, const OUString& rPropName)
714{
715 if (!pShape)
716 return {};
717
719 if (!pFormat)
720 return {};
721
723 = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
724
725 return xPropertySet->getPropertyValue(rPropName);
726}
727
728void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
729 const css::uno::Any& rValue, SdrObject* pObj)
730{
731 // No shape yet? Then nothing to do, initial properties are set by create().
732 if (!pShape)
733 return;
734
735 uno::Any aValue(rValue);
736 nMemberID &= ~CONVERT_TWIPS;
737
738 SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
739 if (!pFormat)
740 return;
741
742 OUString aPropertyName;
743 bool bAdjustX = false;
744 bool bAdjustY = false;
745 bool bAdjustSize = false;
746 switch (nWID)
747 {
748 case RES_HORI_ORIENT:
749 switch (nMemberID)
750 {
752 aPropertyName = UNO_NAME_HORI_ORIENT;
753 break;
755 if (pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)
756 aPropertyName = UNO_NAME_HORI_ORIENT_RELATION;
757 else
758 return;
759 break;
761 aPropertyName = UNO_NAME_HORI_ORIENT_POSITION;
762 bAdjustX = true;
763 break;
764 default:
765 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
766 << o3tl::narrowing<sal_uInt16>(nMemberID)
767 << " (which-id: " << nWID << ")");
768 break;
769 }
770 break;
771 case RES_LR_SPACE:
772 {
773 switch (nMemberID)
774 {
775 case MID_L_MARGIN:
776 aPropertyName = UNO_NAME_LEFT_MARGIN;
777 break;
778 case MID_R_MARGIN:
779 aPropertyName = UNO_NAME_RIGHT_MARGIN;
780 break;
781 default:
782 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
783 << o3tl::narrowing<sal_uInt16>(nMemberID)
784 << " (which-id: " << nWID << ")");
785 break;
786 }
787 break;
788 }
789 case RES_VERT_ORIENT:
790 switch (nMemberID)
791 {
793 aPropertyName = UNO_NAME_VERT_ORIENT;
794 break;
796 if (pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)
797 aPropertyName = UNO_NAME_VERT_ORIENT_RELATION;
798 else
799 return;
800 break;
802 aPropertyName = UNO_NAME_VERT_ORIENT_POSITION;
803 bAdjustY = true;
804 break;
805 default:
806 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
807 << o3tl::narrowing<sal_uInt16>(nMemberID)
808 << " (which-id: " << nWID << ")");
809 break;
810 }
811 break;
812 case RES_FRM_SIZE:
813 switch (nMemberID)
814 {
816 aPropertyName = UNO_NAME_WIDTH_TYPE;
817 break;
819 aPropertyName = UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT;
820 break;
822 aPropertyName = UNO_NAME_RELATIVE_HEIGHT_RELATION;
823 break;
825 aPropertyName = UNO_NAME_RELATIVE_WIDTH_RELATION;
826 break;
827 default:
828 aPropertyName = UNO_NAME_SIZE;
829 bAdjustSize = true;
830 break;
831 }
832 break;
833 case RES_ANCHOR:
834 switch (nMemberID)
835 {
837 {
838 changeAnchor(pShape, pObj);
839 return;
840 }
841 break;
842 default:
843 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
844 << o3tl::narrowing<sal_uInt16>(nMemberID)
845 << " (which-id: " << nWID << ")");
846 break;
847 }
848 break;
849 case FN_TEXT_RANGE:
850 {
851 uno::Reference<text::XTextRange> xRange;
852 rValue >>= xRange;
853 SwUnoInternalPaM aInternalPaM(*pFormat->GetDoc());
854 if (sw::XTextRangeToSwPaM(aInternalPaM, xRange))
855 {
856 SwFormatAnchor aAnchor(pFormat->GetAnchor());
857 aAnchor.SetAnchor(aInternalPaM.Start());
858 pFormat->SetFormatAttr(aAnchor);
859 }
860 }
861 break;
862 case RES_CHAIN:
863 switch (nMemberID)
864 {
866 aPropertyName = UNO_NAME_CHAIN_PREV_NAME;
867 break;
869 aPropertyName = UNO_NAME_CHAIN_NEXT_NAME;
870 break;
871 default:
872 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
873 << o3tl::narrowing<sal_uInt16>(nMemberID)
874 << " (which-id: " << nWID << ")");
875 break;
876 }
877 break;
879 aPropertyName = UNO_NAME_TEXT_VERT_ADJUST;
880 break;
881 case RES_BOX:
882 switch (nMemberID)
883 {
885 aPropertyName = UNO_NAME_LEFT_BORDER_DISTANCE;
886 break;
888 aPropertyName = UNO_NAME_RIGHT_BORDER_DISTANCE;
889 break;
891 aPropertyName = UNO_NAME_TOP_BORDER_DISTANCE;
892 break;
894 aPropertyName = UNO_NAME_BOTTOM_BORDER_DISTANCE;
895 break;
896 default:
897 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
898 << o3tl::narrowing<sal_uInt16>(nMemberID)
899 << " (which-id: " << nWID << ")");
900 break;
901 }
902 break;
903 case RES_OPAQUE:
904 aPropertyName = UNO_NAME_OPAQUE;
905 break;
906 case RES_FRAMEDIR:
907 aPropertyName = UNO_NAME_WRITING_MODE;
908 break;
910 switch (nMemberID)
911 {
913 aPropertyName = UNO_NAME_ALLOW_OVERLAP;
914 break;
915 default:
916 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
917 << o3tl::narrowing<sal_uInt16>(nMemberID)
918 << " (which-id: " << nWID << ")");
919 break;
920 }
921 break;
922 default:
923 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled which-id: "
924 << nWID << " (member-id: "
925 << o3tl::narrowing<sal_uInt16>(nMemberID) << ")");
926 break;
927 }
928
929 if (aPropertyName.isEmpty())
930 return;
931
932 // Position/size should be the text position/size, not the shape one as-is.
933 if (bAdjustX || bAdjustY || bAdjustSize)
934 {
935 changeAnchor(pShape, pObj);
936 tools::Rectangle aRect
937 = getRelativeTextRectangle(pObj ? pObj : pShape->FindRealSdrObject());
938 if (!aRect.IsEmpty())
939 {
940 if (bAdjustX || bAdjustY)
941 {
942 sal_Int32 nValue;
943 if (aValue >>= nValue)
944 {
945 nValue += convertTwipToMm100(bAdjustX ? aRect.Left() : aRect.Top());
946 aValue <<= nValue;
947 }
948 }
949 else if (bAdjustSize)
950 {
951 awt::Size aSize(convertTwipToMm100(aRect.getOpenWidth()),
953 aValue <<= aSize;
954 }
955 }
956 }
957 auto aGuard = SwTextBoxLockGuard(*pShape->GetOtherTextBoxFormats());
958 rtl::Reference<SwXTextFrame> const xPropertySet
959 = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
960 xPropertySet->setPropertyValue(aPropertyName, aValue);
961}
962
964 std::map<const SwFrameFormat*, const SwFrameFormat*>& rLinks)
965{
966 for (const auto pFormat : rFormats)
967 {
968 if (SwFrameFormat* pTextBox = getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
969 rLinks[pFormat] = pTextBox;
970 }
971}
972
973void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrameFormat*>& rNew,
974 SavedLink& rSavedLinks)
975{
976 std::size_t i = 0;
977 for (const auto& rIt : rOld)
978 {
979 auto aTextBoxIt = rSavedLinks.find(rIt.GetFormat());
980 if (aTextBoxIt != rSavedLinks.end())
981 {
982 std::size_t j = 0;
983 for (const auto& rJt : rOld)
984 {
985 if (rJt.GetFormat() == aTextBoxIt->second)
986 rNew[i]->SetFormatAttr(rNew[j]->GetContent());
987 ++j;
988 }
989 }
990 ++i;
991 }
992}
993
994text::TextContentAnchorType SwTextBoxHelper::mapAnchorType(const RndStdIds& rAnchorID)
995{
996 text::TextContentAnchorType aAnchorType;
997 switch (rAnchorID)
998 {
999 case RndStdIds::FLY_AS_CHAR:
1000 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AS_CHARACTER;
1001 break;
1002 case RndStdIds::FLY_AT_CHAR:
1003 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_CHARACTER;
1004 break;
1005 case RndStdIds::FLY_AT_PARA:
1006 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH;
1007 break;
1008 case RndStdIds::FLY_AT_PAGE:
1009 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PAGE;
1010 break;
1011 case RndStdIds::FLY_AT_FLY:
1012 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_FRAME;
1013 break;
1014 default:
1015 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH;
1016 SAL_WARN("sw.core", "SwTextBoxHelper::mapAnchorType: Unknown AnchorType!");
1017 break;
1018 }
1019 return aAnchorType;
1020}
1021
1023 SdrObject* pObj)
1024{
1025 SwFrameFormat* pFormat = getOtherTextBoxFormat(&rShape, RES_DRAWFRMFMT, pObj);
1026 if (!pFormat)
1027 return;
1028
1029 const bool bInlineAnchored = rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR;
1030 const bool bLayoutInCell = rShape.GetFollowTextFlow().GetValue()
1031 && rShape.GetAnchor().GetAnchorNode()
1032 && rShape.GetAnchor().GetAnchorNode()->FindTableNode();
1033 SfxItemSet aTextBoxSet(pFormat->GetDoc()->GetAttrPool(), aFrameFormatSetRange);
1034
1035 SfxItemIter aIter(rSet);
1036 const SfxPoolItem* pItem = aIter.GetCurItem();
1037
1038 do
1039 {
1040 switch (pItem->Which())
1041 {
1042 case RES_VERT_ORIENT:
1043 {
1044 // The new position can be with anchor changing so sync it!
1045 const text::TextContentAnchorType aNewAnchorType
1046 = mapAnchorType(rShape.GetAnchor().GetAnchorId());
1047 syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType),
1048 pObj);
1049 if (bInlineAnchored || bLayoutInCell)
1050 return;
1052
1053 tools::Rectangle aRect
1054 = getRelativeTextRectangle(pObj ? pObj : rShape.FindRealSdrObject());
1055 if (!aRect.IsEmpty())
1056 aOrient.SetPos(aOrient.GetPos() + aRect.Top());
1057
1058 if (rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
1059 && rShape.GetAnchor().GetPageNum() != 0)
1061 aTextBoxSet.Put(aOrient);
1062
1063 // restore height (shrunk for extending beyond the page bottom - tdf#91260)
1064 SwFormatFrameSize aSize(pFormat->GetFrameSize());
1065 if (!aRect.IsEmpty())
1066 {
1067 aSize.SetHeight(aRect.getOpenHeight());
1068 aTextBoxSet.Put(aSize);
1069 }
1070 }
1071 break;
1072 case RES_HORI_ORIENT:
1073 {
1074 // The new position can be with anchor changing so sync it!
1075 const text::TextContentAnchorType aNewAnchorType
1076 = mapAnchorType(rShape.GetAnchor().GetAnchorId());
1077 syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType),
1078 pObj);
1079 if (bInlineAnchored || bLayoutInCell)
1080 return;
1082
1083 tools::Rectangle aRect
1084 = getRelativeTextRectangle(pObj ? pObj : rShape.FindRealSdrObject());
1085 if (!aRect.IsEmpty())
1086 aOrient.SetPos(aOrient.GetPos() + aRect.Left());
1087
1088 if (rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
1089 && rShape.GetAnchor().GetPageNum() != 0)
1091 aTextBoxSet.Put(aOrient);
1092 }
1093 break;
1094 case RES_FRM_SIZE:
1095 {
1096 // In case the shape got resized, then we need to adjust both
1097 // the position and the size of the textbox (e.g. larger
1098 // rounded edges of a rectangle -> need to push right/down the
1099 // textbox).
1100 SwFormatVertOrient aVertOrient(rShape.GetVertOrient());
1101 SwFormatHoriOrient aHoriOrient(rShape.GetHoriOrient());
1102 SwFormatFrameSize aSize(pFormat->GetFrameSize());
1103
1104 tools::Rectangle aRect
1105 = getRelativeTextRectangle(pObj ? pObj : rShape.FindRealSdrObject());
1106 if (!aRect.IsEmpty())
1107 {
1108 if (!bInlineAnchored)
1109 {
1110 aVertOrient.SetPos(
1111 (pObj ? pObj->GetRelativePos().getX() : aVertOrient.GetPos())
1112 + aRect.Top());
1113 aHoriOrient.SetPos(
1114 (pObj ? pObj->GetRelativePos().getY() : aHoriOrient.GetPos())
1115 + aRect.Left());
1116
1117 aTextBoxSet.Put(aVertOrient);
1118 aTextBoxSet.Put(aHoriOrient);
1119 }
1120
1121 aSize.SetWidth(aRect.getOpenWidth());
1122 aSize.SetHeight(aRect.getOpenHeight());
1123 aTextBoxSet.Put(aSize);
1124 }
1125 }
1126 break;
1127 case RES_ANCHOR:
1128 {
1129 if (pItem->StaticWhichCast(RES_ANCHOR) == rShape.GetAnchor())
1130 // the anchor have to be synced
1131 {
1132 const text::TextContentAnchorType aNewAnchorType
1133 = mapAnchorType(rShape.GetAnchor().GetAnchorId());
1135 uno::Any(aNewAnchorType), pObj);
1136 }
1137 else
1138 {
1139 SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrameAttr: The anchor of the "
1140 "shape different from the textframe!");
1141 }
1142 }
1143 break;
1144 default:
1145 SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrameAttr: unhandled which-id: "
1146 << pItem->Which());
1147 break;
1148 }
1149
1150 pItem = aIter.NextItem();
1151 } while (pItem && (0 != pItem->Which()));
1152
1153 if (aTextBoxSet.Count())
1154 {
1155 auto aGuard = SwTextBoxLockGuard(*rShape.GetOtherTextBoxFormats());
1156 pFormat->SetFormatAttr(aTextBoxSet);
1157 }
1158 DoTextBoxZOrderCorrection(&rShape, pObj);
1159}
1160
1162{
1163 if (!pObj)
1164 return;
1165 uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY);
1166 if (!xShape)
1167 return;
1168 uno::Reference<beans::XPropertySet> const xPropertySet(xShape, uno::UNO_QUERY);
1169
1170 auto pParentFormat = getOtherTextBoxFormat(getOtherTextBoxFormat(xShape), RES_FLYFRMFMT);
1171 if (!pParentFormat)
1172 return;
1173
1174 // Sync the padding
1175 syncProperty(pParentFormat, UNO_NAME_TEXT_LEFTDIST,
1176 xPropertySet->getPropertyValue(UNO_NAME_TEXT_LEFTDIST), pObj);
1178 xPropertySet->getPropertyValue(UNO_NAME_TEXT_RIGHTDIST), pObj);
1180 xPropertySet->getPropertyValue(UNO_NAME_TEXT_UPPERDIST), pObj);
1182 xPropertySet->getPropertyValue(UNO_NAME_TEXT_LOWERDIST), pObj);
1183
1184 // Sync the text aligning
1186 xPropertySet->getPropertyValue(UNO_NAME_TEXT_VERTADJUST), pObj);
1188 xPropertySet->getPropertyValue(UNO_NAME_TEXT_HORZADJUST), pObj);
1189
1190 // tdf137803: Sync autogrow:
1191 const bool bIsAutoGrow
1192 = xPropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT).get<bool>();
1193 const bool bIsAutoWrap = xPropertySet->getPropertyValue(UNO_NAME_TEXT_WORDWRAP).get<bool>();
1194
1195 syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, uno::Any(bIsAutoGrow),
1196 pObj);
1197
1199 uno::Any(bIsAutoWrap ? text::SizeType::FIX : text::SizeType::MIN), pObj);
1200
1201 changeAnchor(pParentFormat, pObj);
1202 DoTextBoxZOrderCorrection(pParentFormat, pObj);
1203}
1204
1206{
1207 if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
1208 {
1209 if (!isAnchorSyncNeeded(pShape, pFormat))
1210 {
1211 doTextBoxPositioning(pShape, pObj);
1212 DoTextBoxZOrderCorrection(pShape, pObj);
1213 if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR
1214 && pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR
1215 && pFormat->GetVertOrient().GetRelationOrient() != text::RelOrientation::PRINT_AREA)
1216 {
1217 SwFormatVertOrient aTmp = pFormat->GetVertOrient();
1218 aTmp.SetRelationOrient(text::RelOrientation::PRINT_AREA);
1219 pFormat->SetFormatAttr(aTmp);
1220 }
1221
1222 return false;
1223 }
1224
1225 const SwFormatAnchor& rOldAnch = pFormat->GetAnchor();
1226 const SwFormatAnchor& rNewAnch = pShape->GetAnchor();
1227
1228 const auto pOldCnt = rOldAnch.GetContentAnchor();
1229 const auto pNewCnt = rNewAnch.GetContentAnchor();
1230
1231 const uno::Any aShapeHorRelOrient(pShape->GetHoriOrient().GetRelationOrient());
1232
1233 try
1234 {
1235 auto aGuard = SwTextBoxLockGuard(*pShape->GetOtherTextBoxFormats());
1236 ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
1237 rtl::Reference<SwXTextFrame> const xPropertySet
1238 = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
1239 if (pOldCnt && rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
1240 && rNewAnch.GetPageNum())
1241 {
1242 uno::Any aValue(text::TextContentAnchorType_AT_PAGE);
1243 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION, aShapeHorRelOrient);
1244 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1245 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO,
1246 uno::Any(rNewAnch.GetPageNum()));
1247 }
1248 else if (rOldAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE && pNewCnt)
1249 {
1250 if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1251 {
1252 assert(pNewCnt);
1253 uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
1254 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1255 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1256 uno::Any(text::RelOrientation::CHAR));
1257 xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
1258 uno::Any(text::RelOrientation::PRINT_AREA));
1259 SwFormatAnchor aPos(pFormat->GetAnchor());
1260 aPos.SetAnchor(pNewCnt);
1261 pFormat->SetFormatAttr(aPos);
1262 }
1263 else
1264 {
1265 uno::Any aValue(mapAnchorType(rNewAnch.GetAnchorId()));
1266 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1267 aShapeHorRelOrient);
1268 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1269 pFormat->SetFormatAttr(rNewAnch);
1270 }
1271 }
1272 else
1273 {
1274 if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1275 {
1276 assert(pNewCnt);
1277 uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
1278 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1279 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1280 uno::Any(text::RelOrientation::CHAR));
1281 xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
1282 uno::Any(text::RelOrientation::PRINT_AREA));
1283 SwFormatAnchor aPos(pFormat->GetAnchor());
1284 aPos.SetAnchor(pNewCnt);
1285 pFormat->SetFormatAttr(aPos);
1286 }
1287 else
1288 {
1289 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1290 aShapeHorRelOrient);
1291 if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
1292 && rNewAnch.GetPageNum() == 0)
1293 {
1294 pFormat->SetFormatAttr(SwFormatAnchor(RndStdIds::FLY_AT_PAGE, 1));
1295 }
1296 else
1297 pFormat->SetFormatAttr(pShape->GetAnchor());
1298 }
1299 }
1300 }
1301 catch (uno::Exception& e)
1302 {
1303 SAL_WARN("sw.core", "SwTextBoxHelper::changeAnchor(): " << e.Message);
1304 }
1305
1306 doTextBoxPositioning(pShape, pObj);
1307 DoTextBoxZOrderCorrection(pShape, pObj);
1308 return true;
1309 }
1310
1311 return false;
1312}
1313
1315{
1316 // Set the position of the textboxes according to the position of its shape-pair
1317 const bool bIsGroupObj = (pObj != pShape->FindRealSdrObject()) && pObj;
1318 if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
1319 {
1320 // Do not create undo entry for the positioning
1321 ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
1322 auto aGuard = SwTextBoxLockGuard(*pShape->GetOtherTextBoxFormats());
1323 // Special treatment for AS_CHAR textboxes:
1324 if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1325 {
1326 // Get the text area of the shape
1327 tools::Rectangle aRect
1328 = getRelativeTextRectangle(pObj ? pObj : pShape->FindRealSdrObject());
1329
1330 // Get the left spacing of the text area of the shape
1331 auto nLeftSpace = pShape->GetLRSpace().GetLeft();
1332
1333 // Set the textbox position at the X-axis:
1334 SwFormatHoriOrient aNewHOri(pFormat->GetHoriOrient());
1335 if (bIsGroupObj && aNewHOri.GetHoriOrient() != text::HoriOrientation::NONE)
1337 aNewHOri.SetPos(aRect.Left() + nLeftSpace
1338 + (bIsGroupObj ? pObj->GetRelativePos().getX() : 0));
1339 SwFormatVertOrient aNewVOri(pFormat->GetVertOrient());
1340
1341 // Special handling of group textboxes
1342 if (bIsGroupObj)
1343 {
1344 // There are the following cases:
1345 // case 1: The textbox should be in that position where the shape is.
1346 // case 2: The shape has negative offset so that have to be subtracted
1347 // case 3: The shape and its parent shape also has negative offset, so subtract
1348 aNewVOri.SetPos(
1349 ((pObj->GetRelativePos().getY()) > 0
1350 ? (pShape->GetVertOrient().GetPos() > 0
1351 ? pObj->GetRelativePos().getY()
1352 : pObj->GetRelativePos().getY() - pShape->GetVertOrient().GetPos())
1353 : (pShape->GetVertOrient().GetPos() > 0
1354 ? 0 // Is this can be a variation?
1355 : pObj->GetRelativePos().getY() - pShape->GetVertOrient().GetPos()))
1356 + aRect.Top());
1357 }
1358 else
1359 {
1360 // Simple textboxes: vertical position equals to the vertical offset of the shape
1361 aNewVOri.SetPos(
1362 ((pShape->GetVertOrient().GetPos()) > 0 ? pShape->GetVertOrient().GetPos() : 0)
1363 + aRect.Top());
1364 }
1365
1366 // Special cases when the shape is aligned to the line
1368 {
1370 switch (pShape->GetVertOrient().GetVertOrient())
1371 {
1372 // Top aligned shape
1373 case text::VertOrientation::TOP:
1374 case text::VertOrientation::CHAR_TOP:
1375 case text::VertOrientation::LINE_TOP:
1376 {
1377 aNewVOri.SetPos(aNewVOri.GetPos() - pShape->GetFrameSize().GetHeight());
1378 break;
1379 }
1380 // Bottom aligned shape
1381 case text::VertOrientation::BOTTOM:
1382 case text::VertOrientation::CHAR_BOTTOM:
1383 case text::VertOrientation::LINE_BOTTOM:
1384 {
1385 aNewVOri.SetPos(aNewVOri.GetPos() + pShape->GetFrameSize().GetHeight());
1386 break;
1387 }
1388 // Center aligned shape
1389 case text::VertOrientation::CENTER:
1390 case text::VertOrientation::CHAR_CENTER:
1391 case text::VertOrientation::LINE_CENTER:
1392 {
1393 aNewVOri.SetPos(aNewVOri.GetPos()
1394 + std::lroundf(pShape->GetFrameSize().GetHeight() / 2));
1395 break;
1396 }
1397 default:
1398 break;
1399 }
1400 }
1401
1402 pFormat->SetFormatAttr(aNewHOri);
1403 pFormat->SetFormatAttr(aNewVOri);
1404 }
1405 // Other cases when the shape has different anchor from AS_CHAR
1406 else
1407 {
1408 // Text area of the shape
1409 tools::Rectangle aRect
1410 = getRelativeTextRectangle(pObj ? pObj : pShape->FindRealSdrObject());
1411
1412 // X Offset of the shape spacing
1413 auto nLeftSpace = pShape->GetLRSpace().GetLeft();
1414
1415 // Set the same position as the (child) shape has
1416 SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
1417 if (bIsGroupObj && aNewHOri.GetHoriOrient() != text::HoriOrientation::NONE)
1419
1420 aNewHOri.SetPos(
1421 (bIsGroupObj && pObj ? pObj->GetRelativePos().getX() : aNewHOri.GetPos())
1422 + aRect.Left());
1423 SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
1424 aNewVOri.SetPos(
1425 (bIsGroupObj && pObj ? pObj->GetRelativePos().getY() : aNewVOri.GetPos())
1426 + aRect.Top());
1427
1428 // Get the distance of the child shape inside its parent
1429 const auto& nInshapePos
1430 = pObj ? pObj->GetRelativePos() - pShape->FindRealSdrObject()->GetRelativePos()
1431 : Point();
1432
1433 // Special case: the shape has relative position from the page
1434 if (pShape->GetHoriOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME
1435 && pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AT_PAGE)
1436 {
1437 aNewHOri.SetRelationOrient(text::RelOrientation::PAGE_FRAME);
1438 aNewHOri.SetPos(pShape->GetHoriOrient().GetPos() + nInshapePos.getX()
1439 + aRect.Left());
1440 }
1441
1442 if (pShape->GetVertOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME
1443 && pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AT_PAGE)
1444 {
1445 aNewVOri.SetRelationOrient(text::RelOrientation::PAGE_FRAME);
1446 aNewVOri.SetPos(pShape->GetVertOrient().GetPos() + nInshapePos.getY()
1447 + aRect.Top());
1448 }
1449
1450 // Other special case: shape is inside a table or floating table following the text flow
1451 if (pShape->GetFollowTextFlow().GetValue() && pShape->GetAnchor().GetAnchorNode()
1452 && pShape->GetAnchor().GetAnchorNode()->FindTableNode())
1453 {
1454 // Table position
1455 Point nTableOffset;
1456 // Floating table
1457 if (auto pFly
1459 {
1460 if (auto pFlyFormat = pFly->GetFlyFormat())
1461 {
1462 nTableOffset.setX(pFlyFormat->GetHoriOrient().GetPos());
1463 nTableOffset.setY(pFlyFormat->GetVertOrient().GetPos());
1464 }
1465 }
1466 else
1467 // Normal table
1468 {
1469 auto pTableNode = pShape->GetAnchor().GetAnchorNode()->FindTableNode();
1470 if (auto pTableFormat = pTableNode->GetTable().GetFrameFormat())
1471 {
1472 nTableOffset.setX(pTableFormat->GetHoriOrient().GetPos());
1473 nTableOffset.setY(pTableFormat->GetVertOrient().GetPos());
1474 }
1475 }
1476
1477 // Add the table positions to the textbox.
1478 aNewHOri.SetPos(aNewHOri.GetPos() + nTableOffset.getX() + nLeftSpace);
1479 if (pShape->GetVertOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME
1480 || pShape->GetVertOrient().GetRelationOrient()
1481 == text::RelOrientation::PAGE_PRINT_AREA)
1482 aNewVOri.SetPos(aNewVOri.GetPos() + nTableOffset.getY());
1483 }
1484
1485 pFormat->SetFormatAttr(aNewHOri);
1486 pFormat->SetFormatAttr(aNewVOri);
1487 }
1488 return true;
1489 }
1490
1491 return false;
1492}
1493
1495{
1496 if (!pShape || !pObj)
1497 return false;
1498
1499 if (auto pTextBox = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
1500 {
1501 auto aGuard = SwTextBoxLockGuard(*pShape->GetOtherTextBoxFormats());
1502 const auto& rSize = getRelativeTextRectangle(pObj).GetSize();
1503 if (!rSize.IsEmpty())
1504 {
1505 SwFormatFrameSize aSize(pTextBox->GetFrameSize());
1506 aSize.SetSize(rSize);
1507 return pTextBox->SetFormatAttr(aSize);
1508 }
1509 }
1510
1511 return false;
1512}
1513
1515{
1516 // TODO: do this with group shape textboxes.
1517 SdrObject* pShpObj = nullptr;
1518
1519 pShpObj = pShape->FindRealSdrObject();
1520
1521 if (pShpObj)
1522 {
1523 auto pTextBox = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
1524 if (!pTextBox)
1525 return false;
1526 SdrObject* pFrmObj = pTextBox->FindRealSdrObject();
1527 if (!pFrmObj)
1528 {
1529 // During loading there is no ready SdrObj for z-ordering, so create and cache it here
1530 pFrmObj
1531 = SwXTextFrame::GetOrCreateSdrObject(*dynamic_cast<SwFlyFrameFormat*>(pTextBox));
1532 }
1533 if (pFrmObj)
1534 {
1535 // Get the draw model from the doc
1536 SwDrawModel* pDrawModel
1538 if (pDrawModel)
1539 {
1540 // Not really sure this will work on all pages, but it seems it will.
1541 auto pPage = pDrawModel->GetPage(0);
1542 // Recalc all Z-orders
1543 pPage->RecalcObjOrdNums();
1544 // Here is a counter avoiding running to in infinity:
1545 sal_uInt16 nIterator = 0;
1546 // If the shape is behind the frame, is good, but if there are some objects
1547 // between of them that is wrong so put the frame exactly one level higher
1548 // than the shape.
1549 if (pFrmObj->GetOrdNum() > pShpObj->GetOrdNum())
1550 pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pShpObj->GetOrdNum() + 1);
1551 else
1552 // Else, if the frame is behind the shape, bring to the front of it.
1553 while (pFrmObj->GetOrdNum() <= pShpObj->GetOrdNum())
1554 {
1555 pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pFrmObj->GetOrdNum() + 1);
1556 // If there is any problem with the indexes, do not run over the infinity
1557 if (pPage->GetObjCount() == pFrmObj->GetOrdNum())
1558 break;
1559 ++nIterator;
1560 if (nIterator > 300)
1561 break; // Do not run to infinity
1562 }
1563 pPage->RecalcObjOrdNums();
1564 return true; // Success
1565 }
1566 SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1567 "No Valid Draw model for SdrObject for the shape!");
1568 }
1569 SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1570 "No Valid SdrObject for the frame!");
1571 }
1572 SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1573 "No Valid SdrObject for the shape!");
1574
1575 return false;
1576}
1577
1579 SwFrameFormat* pFormat, SdrObject* pObj)
1580{
1581 if (auto pChildren = pObj->getChildrenOfSdrObject())
1582 {
1583 for (size_t i = 0; i < pChildren->GetObjCount(); ++i)
1584 synchronizeGroupTextBoxProperty(pFunc, pFormat, pChildren->GetObj(i));
1585 }
1586 else
1587 {
1588 (*pFunc)(pFormat, pObj);
1589 }
1590}
1591
1592std::vector<SwFrameFormat*> SwTextBoxHelper::CollectTextBoxes(const SdrObject* pGroupObject,
1593 SwFrameFormat* pFormat)
1594{
1595 std::vector<SwFrameFormat*> vRet;
1596 if (auto pChildren = pGroupObject->getChildrenOfSdrObject())
1597 {
1598 for (size_t i = 0; i < pChildren->GetObjCount(); ++i)
1599 {
1600 auto pChildTextBoxes = CollectTextBoxes(pChildren->GetObj(i), pFormat);
1601 for (auto& rChildTextBox : pChildTextBoxes)
1602 vRet.push_back(rChildTextBox);
1603 }
1604 }
1605 else
1606 {
1607 if (isTextBox(pFormat, RES_DRAWFRMFMT, pGroupObject))
1608 vRet.push_back(getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT, pGroupObject));
1609 }
1610 return vRet;
1611}
1612
1614{
1615 if (!pFirst)
1616 return false;
1617
1618 if (!pSecond)
1619 return false;
1620
1621 if (pFirst == pSecond)
1622 return false;
1623
1624 if (!pFirst->GetOtherTextBoxFormats())
1625 return false;
1626
1627 if (!pSecond->GetOtherTextBoxFormats())
1628 return false;
1629
1630 if (pFirst->GetOtherTextBoxFormats() != pSecond->GetOtherTextBoxFormats())
1631 return false;
1632
1633 if (pFirst->GetOtherTextBoxFormats()->GetOwnerShape() == pSecond
1634 || pFirst == pSecond->GetOtherTextBoxFormats()->GetOwnerShape())
1635 {
1636 const auto& rShapeAnchor
1637 = pFirst->Which() == RES_DRAWFRMFMT ? pFirst->GetAnchor() : pSecond->GetAnchor();
1638 const auto& rFrameAnchor
1639 = pFirst->Which() == RES_FLYFRMFMT ? pFirst->GetAnchor() : pSecond->GetAnchor();
1640
1641 if (rShapeAnchor.GetAnchorId() == rFrameAnchor.GetAnchorId())
1642 {
1643 if (rShapeAnchor.GetAnchorNode() && rFrameAnchor.GetAnchorNode())
1644 {
1645 if (*rShapeAnchor.GetContentAnchor() != *rFrameAnchor.GetContentAnchor())
1646 return true;
1647
1648 return false;
1649 }
1650
1651 if (rShapeAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE
1652 && rFrameAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
1653 {
1654 if (rShapeAnchor.GetPageNum() == rFrameAnchor.GetPageNum())
1655 return false;
1656 else
1657 return true;
1658 }
1659
1660 return true;
1661 }
1662
1663 if (rShapeAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR
1664 && rFrameAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
1665 {
1666 if (rShapeAnchor.GetAnchorNode() && rFrameAnchor.GetAnchorNode())
1667 {
1668 if (*rShapeAnchor.GetContentAnchor() != *rFrameAnchor.GetContentAnchor())
1669 return true;
1670
1671 return false;
1672 }
1673 }
1674 return true;
1675 }
1676 return false;
1677}
1678
1680{
1681 assert(pOwnerShape);
1682 assert(pOwnerShape->Which() == RES_DRAWFRMFMT);
1683
1684 m_bIsCloningInProgress = false;
1685 m_bLock = false;
1686
1687 m_pOwnerShapeFormat = pOwnerShape;
1688 if (!m_pTextBoxes.empty())
1689 m_pTextBoxes.clear();
1690}
1691
1693{
1694 if (m_pTextBoxes.size() != 0)
1695 {
1696 SAL_WARN("sw.core", "SwTextBoxNode::~SwTextBoxNode(): Text-Box-Vector still not empty!");
1697 assert(false);
1698 }
1699}
1700
1701void SwTextBoxNode::AddTextBox(SdrObject* pDrawObject, SwFrameFormat* pNewTextBox)
1702{
1703 assert(pNewTextBox);
1704 assert(pNewTextBox->Which() == RES_FLYFRMFMT);
1705
1706 assert(pDrawObject);
1707
1708 SwTextBoxElement aElem;
1709 aElem.m_pDrawObject = pDrawObject;
1710 aElem.m_pTextBoxFormat = pNewTextBox;
1711
1712 for (const auto& rE : m_pTextBoxes)
1713 {
1714 if (rE.m_pDrawObject == pDrawObject || rE.m_pTextBoxFormat == pNewTextBox)
1715 {
1716 SAL_WARN("sw.core", "SwTextBoxNode::AddTextBox(): Already exist!");
1717 return;
1718 }
1719 }
1720
1721 auto pSwFlyDraw = dynamic_cast<SwFlyDrawObj*>(pDrawObject);
1722 if (pSwFlyDraw)
1723 {
1724 pSwFlyDraw->SetTextBox(true);
1725 }
1726 m_pTextBoxes.push_back(aElem);
1727}
1728
1729void SwTextBoxNode::DelTextBox(const SdrObject* pDrawObject, bool bDelFromDoc)
1730{
1731 assert(pDrawObject);
1732 if (m_pTextBoxes.empty())
1733 return;
1734
1735 for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end();)
1736 {
1737 if (it->m_pDrawObject == pDrawObject)
1738 {
1739 if (bDelFromDoc)
1740 {
1741 it->m_pTextBoxFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(
1742 it->m_pTextBoxFormat);
1743 // What about m_pTextBoxes? So, when the DelLayoutFormat() removes the format
1744 // then the ~SwFrameFormat() will call this method again to remove the entry.
1745 return;
1746 }
1747 else
1748 {
1749 it = m_pTextBoxes.erase(it);
1750 return;
1751 }
1752 }
1753 ++it;
1754 }
1755
1756 SAL_WARN("sw.core", "SwTextBoxNode::DelTextBox(): Not found!");
1757}
1758
1759void SwTextBoxNode::DelTextBox(const SwFrameFormat* pTextBox, bool bDelFromDoc)
1760{
1761 if (m_pTextBoxes.empty())
1762 return;
1763
1764 for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end();)
1765 {
1766 if (it->m_pTextBoxFormat == pTextBox)
1767 {
1768 if (bDelFromDoc)
1769 {
1770 it->m_pTextBoxFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(
1771 it->m_pTextBoxFormat);
1772 // What about m_pTextBoxes? So, when the DelLayoutFormat() removes the format
1773 // then the ~SwFrameFormat() will call this method again to remove the entry.
1774 return;
1775 }
1776 else
1777 {
1778 it = m_pTextBoxes.erase(it);
1779 return;
1780 }
1781 }
1782 ++it;
1783 }
1784
1785 SAL_WARN("sw.core", "SwTextBoxNode::DelTextBox(): Not found!");
1786}
1787
1789{
1790 assert(pDrawObject);
1791 assert(m_pOwnerShapeFormat);
1792
1793 if (auto& pTextBoxes = m_pOwnerShapeFormat->GetOtherTextBoxFormats())
1794 {
1795 if (size_t(pTextBoxes.use_count()) != pTextBoxes->GetTextBoxCount() + size_t(1))
1796 {
1797 SAL_WARN("sw.core", "SwTextBoxNode::GetTextBox(): RefCount and TexBox count mismatch!");
1798 assert(false);
1799 }
1800 }
1801
1802 if (m_bLock)
1803 return nullptr;
1804
1805 if (!m_pTextBoxes.empty())
1806 {
1807 for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
1808 {
1809 if (it->m_pDrawObject == pDrawObject)
1810 {
1811 return it->m_pTextBoxFormat;
1812 }
1813 }
1814 SAL_WARN("sw.core", "SwTextBoxNode::GetTextBox(): Not found!");
1815 }
1816
1817 return nullptr;
1818}
1819
1821{
1822 // If this called from ~SwDoc(), then only the address entries
1823 // have to be removed, the format will be deleted by the
1824 // the mpSpzFrameFormatTable->DeleteAndDestroyAll() in ~SwDoc()!
1826 {
1827 m_pTextBoxes.clear();
1828 return;
1829 }
1830
1831 // For loop control
1832 sal_uInt16 nLoopCount = 0;
1833
1834 // Reference not enough, copy needed.
1835 const size_t nTextBoxCount = m_pTextBoxes.size();
1836
1837 // For loop has problems: When one entry deleted, the iterator has
1838 // to be refreshed according to the new situation. So using While() instead.
1839 while (!m_pTextBoxes.empty())
1840 {
1841 // Delete the last textbox of the vector from the doc
1842 // (what will call deregister in ~SwFrameFormat()
1844 m_pTextBoxes.back().m_pTextBoxFormat);
1845
1846 // Check if we are looping
1847 if (nLoopCount > (nTextBoxCount + 1))
1848 {
1849 SAL_WARN("sw.core", "SwTextBoxNode::ClearAll(): Maximum loop count reached!");
1850 break;
1851 }
1852 else
1853 {
1854 nLoopCount++;
1855 }
1856 }
1857
1858 // Ensure the vector is empty.
1859 if (!m_pTextBoxes.empty())
1860 {
1861 SAL_WARN("sw.core", "SwTextBoxNode::ClearAll(): Text-Box-Vector still not empty!");
1862 assert(false);
1863 }
1864}
1865
1866bool SwTextBoxNode::IsGroupTextBox() const { return m_pTextBoxes.size() > 1; }
1867
1868std::map<SdrObject*, SwFrameFormat*> SwTextBoxNode::GetAllTextBoxes() const
1869{
1870 std::map<SdrObject*, SwFrameFormat*> aRet;
1871 for (auto& rElem : m_pTextBoxes)
1872 {
1873 aRet.emplace(rElem.m_pDrawObject, rElem.m_pTextBoxFormat);
1874 }
1875 return aRet;
1876}
1877
1878void SwTextBoxNode::Clone(SwDoc* pDoc, const SwFormatAnchor& rNewAnc, SwFrameFormat* o_pTarget,
1879 bool bSetAttr, bool bMakeFrame) const
1880{
1881 if (!o_pTarget || !pDoc)
1882 return;
1883
1884 if (o_pTarget->Which() != RES_DRAWFRMFMT)
1885 return;
1886
1888 return;
1889
1891
1892 Clone_Impl(pDoc, rNewAnc, o_pTarget, m_pOwnerShapeFormat->FindSdrObject(),
1893 o_pTarget->FindSdrObject(), bSetAttr, bMakeFrame);
1894
1895 m_bIsCloningInProgress = false;
1896
1897 for (auto& rElem : m_pTextBoxes)
1898 {
1903 }
1904}
1905
1906void SwTextBoxNode::Clone_Impl(SwDoc* pDoc, const SwFormatAnchor& rNewAnc, SwFrameFormat* o_pTarget,
1907 const SdrObject* pSrcObj, SdrObject* pDestObj, bool bSetAttr,
1908 bool bMakeFrame) const
1909{
1910 if (!pSrcObj || !pDestObj)
1911 return;
1912
1913 auto pSrcList = pSrcObj->getChildrenOfSdrObject();
1914 auto pDestList = pDestObj->getChildrenOfSdrObject();
1915
1916 if (pSrcList && pDestList)
1917 {
1918 if (pSrcList->GetObjCount() != pDestList->GetObjCount())
1919 {
1920 SAL_WARN("sw.core", "SwTextBoxNode::Clone_Impl(): Difference between the shapes!");
1921 return;
1922 }
1923
1924 for (size_t i = 0; i < pSrcList->GetObjCount(); ++i)
1925 {
1926 Clone_Impl(pDoc, rNewAnc, o_pTarget, pSrcList->GetObj(i), pDestList->GetObj(i),
1927 bSetAttr, bMakeFrame);
1928 }
1929 return;
1930 }
1931
1932 if (!pSrcList && !pDestList)
1933 {
1934 if (auto pSrcFormat = GetTextBox(pSrcObj))
1935 {
1936 SwFormatAnchor aNewAnchor(rNewAnc);
1937 if (aNewAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1938 {
1939 aNewAnchor.SetType(RndStdIds::FLY_AT_CHAR);
1940
1941 if (!bMakeFrame)
1942 bMakeFrame = true;
1943 }
1944
1945 if (auto pTargetFormat = pDoc->getIDocumentLayoutAccess().CopyLayoutFormat(
1946 *pSrcFormat, aNewAnchor, bSetAttr, bMakeFrame))
1947 {
1948 if (!o_pTarget->GetOtherTextBoxFormats())
1949 {
1950 auto pNewTextBoxes = std::make_shared<SwTextBoxNode>(SwTextBoxNode(o_pTarget));
1951 o_pTarget->SetOtherTextBoxFormats(pNewTextBoxes);
1952 pNewTextBoxes->AddTextBox(pDestObj, pTargetFormat);
1953 pTargetFormat->SetOtherTextBoxFormats(pNewTextBoxes);
1954 }
1955 else
1956 {
1957 o_pTarget->GetOtherTextBoxFormats()->AddTextBox(pDestObj, pTargetFormat);
1958 pTargetFormat->SetOtherTextBoxFormats(o_pTarget->GetOtherTextBoxFormats());
1959 }
1960 o_pTarget->SetFormatAttr(pTargetFormat->GetContent());
1961 }
1962 }
1963 }
1964}
1965
1966/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr auto convertTwipToMm100(N n)
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
virtual SwFrameFormat * CopyLayoutFormat(const SwFrameFormat &rSrc, const SwFormatAnchor &rNewAnchor, bool bSetTextFlyAtt, bool bMakeFrames)=0
virtual void DelLayoutFormat(SwFrameFormat *pFormat)=0
virtual void SetModified()=0
Must be called manually at changes of format.
const SdrPage * GetPage(sal_uInt16 nPgNum) const
SdrObject * GetObj(size_t nNum) const
size_t GetObjCount() const
void RecalcObjOrdNums()
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
const css::uno::WeakReference< css::drawing::XShape > & getWeakUnoShape() const
virtual css::uno::Reference< css::drawing::XShape > getUnoShape()
sal_uInt32 GetOrdNum() const
virtual const tools::Rectangle & GetCurrentBoundRect() const
virtual const tools::Rectangle & GetSnapRect() const
virtual SdrObjList * getChildrenOfSdrObject() const
virtual Point GetRelativePos() const
virtual const tools::Rectangle & GetLogicRect() const
bool GetValue() const
const SfxPoolItem * GetCurItem() const
const SfxPoolItem * NextItem()
sal_uInt16 Count() const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
T & StaticWhichCast(TypedWhichId< T > nId)
sal_uInt16 Which() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
tools::Long GetLeft() const
tools::Long GetHeight() const
void SetHeight(tools::Long n)
void SetSize(const Size &rSize)
void SetWidth(tools::Long n)
Definition: doc.hxx:194
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:400
bool IsInDtor() const
Definition: doc.hxx:412
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:150
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:411
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1326
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:161
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:752
SwDocShell * GetDocShell()
Definition: doc.hxx:1359
void SetTextBox(bool bIsTextBox)
Definition: dflyobj.hxx:52
FlyAnchors.
Definition: fmtanchr.hxx:37
sal_uInt16 GetPageNum() const
Definition: fmtanchr.hxx:70
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1586
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
void SetType(RndStdIds nRndId)
Definition: fmtanchr.hxx:68
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:74
SwNode * GetAnchorNode() const
Definition: atrfrm.cxx:1606
Connection (text flow) between two FlyFrames.
Definition: fmtcnct.hxx:32
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const override
Definition: atrfrm.cxx:2172
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:32
Defines the horizontal position of a fly frame.
Definition: fmtornt.hxx:73
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:100
void SetHoriOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:96
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:94
void SetRelationOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:97
SwTwips GetPos() const
Definition: fmtornt.hxx:99
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:95
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
Defines the vertical position of a fly frame.
Definition: fmtornt.hxx:37
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:58
SwTwips GetPos() const
Definition: fmtornt.hxx:62
void SetVertOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:59
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:63
void SetRelationOrient(sal_Int16 eNew)
Definition: fmtornt.hxx:60
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:57
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
const SwFormatChain & GetChain(bool=true) const
Definition: fmtcnct.hxx:70
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
const OUString & GetName() const
Definition: format.hxx:131
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:113
const SwFormatFollowTextFlow & GetFollowTextFlow(bool=true) const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:88
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:115
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:447
Style of a layout element.
Definition: frmfmt.hxx:62
void SetOtherTextBoxFormats(const std::shared_ptr< SwTextBoxNode > &rNew)
Definition: frmfmt.hxx:107
const std::shared_ptr< SwTextBoxNode > & GetOtherTextBoxFormats() const
Definition: frmfmt.hxx:106
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2795
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:141
Specific frame formats (frames, DrawObjects).
const SwStartNode * FindFlyStartNode() const
Definition: node.hxx:220
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:380
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNode & GetPointNode() const
Definition: pam.hxx:283
const SwPosition * Start() const
Definition: pam.hxx:266
static css::uno::Any getByIndex(SdrPage const *pPage, sal_Int32 nIndex)
Get a shape by index, excluding TextBoxes.
static bool doTextBoxPositioning(SwFrameFormat *pShape, SdrObject *pObj)
Does the positioning for the associated textframe of the shape, and returns true on success.
static bool hasTextFrame(const SdrObject *pObj)
Returns true if the SdrObject has a SwTextFrame otherwise false.
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.
static std::vector< SwFrameFormat * > CollectTextBoxes(const SdrObject *pGroupObject, SwFrameFormat *pFormat)
Collect all textboxes of the group given by the pGroupObj Parameter.
static void set(SwFrameFormat *pShape, SdrObject *pObject, css::uno::Reference< css::text::XTextFrame > xNew)
Sets the given textframe as textbox for the given (group member) shape.
static sal_Int32 getCount(const SwDoc &rDoc)
Count number of shapes in the document, excluding TextBoxes.
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 bool DoTextBoxZOrderCorrection(SwFrameFormat *pShape, const SdrObject *pObj)
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.
static void getShapeWrapThrough(const SwFrameFormat *pTextBox, bool &rWrapThrough)
If pTextBox is a textbox, then set rWrapThrough to the surround of its shape.
static css::text::TextContentAnchorType mapAnchorType(const RndStdIds &rAnchorID)
There are two types of enum of anchor type, so this function maps this.
static void restoreLinks(std::set< ZSortFly > &rOld, std::vector< SwFrameFormat * > &rNew, SavedLink &rSavedLinks)
Undo the effect of saveLinks() + individual resetLink() calls.
static bool isAnchorSyncNeeded(const SwFrameFormat *pFirst, const SwFrameFormat *pSecond)
static void create(SwFrameFormat *pShape, SdrObject *pObject, bool bCopyText=false)
Create a TextBox for a shape.
static bool syncTextBoxSize(SwFrameFormat *pShape, SdrObject *pObj)
Sets the correct size of textframe depending on the given SdrObject.
static tools::Rectangle getRelativeTextRectangle(SdrObject *pShape)
Return the textbox rectangle of a draw shape (in relative twips).
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
If we have an associated TextFrame, then return that.
static void getProperty(SwFrameFormat const *pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, css::uno::Any &rValue)
Get a property of the underlying TextFrame.
static void updateTextBoxMargin(SdrObject *pObj)
Copy shape attributes to the text frame.
static bool changeAnchor(SwFrameFormat *pShape, SdrObject *pObj)
Sets the anchor of the associated textframe of the given shape, and returns true on success.
static void syncFlyFrameAttr(SwFrameFormat &rShape, SfxItemSet const &rSet, SdrObject *pObj)
Similar to syncProperty(), but used by the internal API (e.g. for UI purposes).
static void synchronizeGroupTextBoxProperty(bool pFunc(SwFrameFormat *, SdrObject *), SwFrameFormat *pFormat, SdrObject *pObj)
Calls the method given by pFunc with every textboxes of the group given by pFormat.
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
Is the frame format a text box?
static void destroy(const SwFrameFormat *pShape, const SdrObject *pObject)
Destroy a TextBox for a shape.
static sal_Int32 getOrdNum(const SdrObject *pObject)
Get the order of the shape, excluding TextBoxes.
static css::uno::Any queryInterface(const SwFrameFormat *pShape, const css::uno::Type &rType, SdrObject *pObj)
Get interface of a shape's TextBox, if there is any.
std::map< const SwFrameFormat *, const SwFrameFormat * > SavedLink
Maps a draw format to a fly format.
Textboxes are basically textframe + shape pairs.
bool m_bIsCloningInProgress
void AddTextBox(SdrObject *pDrawObject, SwFrameFormat *pNewTextBox)
void Clone_Impl(SwDoc *pDoc, const SwFormatAnchor &rNewAnc, SwFrameFormat *o_pTarget, const SdrObject *pSrcObj, SdrObject *pDestObj, bool bSetAttr, bool bMakeFrame) const
SwFrameFormat * GetTextBox(const SdrObject *pDrawObject) const
std::map< SdrObject *, SwFrameFormat * > GetAllTextBoxes() const
bool IsGroupTextBox() const
void Clone(SwDoc *pDoc, const SwFormatAnchor &rNewAnc, SwFrameFormat *o_pTarget, bool bSetAttr, bool bMakeFrame) const
SwFrameFormat * m_pOwnerShapeFormat
std::vector< SwTextBoxElement > m_pTextBoxes
void DelTextBox(const SdrObject *pDrawObject, bool bDelFromDoc=false)
SwTextBoxNode()=delete
static css::uno::Reference< css::uno::XInterface > MakeInstance(SwServiceType nObjectType, SwDoc &rDoc)
Definition: unocoll.cxx:517
static SW_DLLPUBLIC rtl::Reference< SwXTextFrame > CreateXTextFrame(SwDoc &rDoc, SwFrameFormat *pFrameFormat)
Definition: unoframe.cxx:3223
iterator find(const OUString &rKey)
constexpr Point Center() const
constexpr tools::Long Top() const
tools::Long getOpenHeight() const
constexpr Size GetSize() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
tools::Long getOpenWidth() const
constexpr tools::Long Left() const
constexpr bool IsEmpty() const
#define FN_TEXT_RANGE
Definition: cmdid.h:823
int nCount
float u
EmbeddedObjectRef * pObject
sal_Int16 nValue
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
constexpr TypedWhichId< SvxOpaqueItem > RES_OPAQUE(99)
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(156)
constexpr TypedWhichId< SwFormatFollowTextFlow > RES_FOLLOW_TEXT_FLOW(123)
constexpr TypedWhichId< SwFormatWrapInfluenceOnObjPos > RES_WRAP_INFLUENCE_ON_OBJPOS(125)
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(103)
constexpr TypedWhichId< SwFormatAnchor > RES_ANCHOR(104)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(159)
constexpr TypedWhichId< SwFormatChain > RES_CHAIN(114)
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
constexpr TypedWhichId< SdrTextVertAdjustItem > RES_TEXT_VERT_ADJUST(130)
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
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 >)
sal_Int32 nIndex
Mode eMode
void * p
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
#define LEFT_BORDER_DISTANCE
#define MID_R_MARGIN
#define TOP_BORDER_DISTANCE
#define RIGHT_BORDER_DISTANCE
#define BOTTOM_BORDER_DISTANCE
#define MID_L_MARGIN
int i
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange, ::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1102
QPRO_FUNC_TYPE nType
static SfxItemSet & rSet
SVXCORE_DLLPUBLIC SdrTextObj * DynCastSdrTextObj(SdrObject *)
RndStdIds
static void lcl_queryInterface(const SwFrameFormat *pShape, uno::Any &rAny, SdrObject *pObj)
unsigned char sal_uInt8
#define MID_HORIORIENT_RELATION
Definition: unomid.h:39
#define MID_FRMSIZE_REL_WIDTH_RELATION
Definition: unomid.h:87
#define MID_FRMSIZE_REL_HEIGHT_RELATION
Definition: unomid.h:88
#define MID_VERTORIENT_RELATION
Definition: unomid.h:35
#define MID_VERTORIENT_POSITION
Definition: unomid.h:36
#define MID_FRMSIZE_WIDTH_TYPE
Definition: unomid.h:86
#define MID_VERTORIENT_ORIENT
Definition: unomid.h:34
#define MID_HORIORIENT_POSITION
Definition: unomid.h:40
#define MID_FOLLOW_TEXT_FLOW
Definition: unomid.h:152
#define MID_ANCHOR_ANCHORTYPE
Definition: unomid.h:43
#define MID_CHAIN_PREVNAME
Definition: unomid.h:56
#define MID_CHAIN_NEXTNAME
Definition: unomid.h:57
#define MID_FRMSIZE_IS_AUTO_HEIGHT
Definition: unomid.h:77
#define MID_FRMSIZE_SIZE
Definition: unomid.h:70
#define MID_HORIORIENT_ORIENT
Definition: unomid.h:38
#define MID_CHAIN_NAME
Definition: unomid.h:58
#define MID_ALLOW_OVERLAP
Definition: unomid.h:149
constexpr OUStringLiteral UNO_NAME_FILL_TRANSPARENCE
constexpr OUStringLiteral UNO_NAME_TEXT_LOWERDIST
#define UNO_NAME_TEXT_VERT_ADJUST
Definition: unoprnms.hxx:861
#define UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT
Definition: unoprnms.hxx:596
#define UNO_NAME_SIZE
Definition: unoprnms.hxx:309
#define UNO_NAME_BOTTOM_BORDER_DISTANCE
Definition: unoprnms.hxx:367
constexpr OUStringLiteral UNO_NAME_TEXT_UPPERDIST
#define UNO_NAME_VERT_ORIENT_POSITION
Definition: unoprnms.hxx:337
#define UNO_NAME_HORI_ORIENT_RELATION
Definition: unoprnms.hxx:269
#define UNO_NAME_RIGHT_BORDER
Definition: unoprnms.hxx:360
#define UNO_NAME_TOP_BORDER_DISTANCE
Definition: unoprnms.hxx:366
#define UNO_NAME_RELATIVE_WIDTH_RELATION
Definition: unoprnms.hxx:194
#define UNO_NAME_LEFT_BORDER
Definition: unoprnms.hxx:359
#define UNO_NAME_SURROUND
Definition: unoprnms.hxx:316
#define UNO_NAME_VERT_ORIENT_RELATION
Definition: unoprnms.hxx:338
#define UNO_NAME_HORI_ORIENT_POSITION
Definition: unoprnms.hxx:270
#define UNO_NAME_RIGHT_MARGIN
Definition: unoprnms.hxx:72
#define UNO_NAME_CHAIN_PREV_NAME
Definition: unoprnms.hxx:238
#define UNO_NAME_LEFT_MARGIN
Definition: unoprnms.hxx:71
#define UNO_NAME_WIDTH_TYPE
Definition: unoprnms.hxx:747
constexpr OUStringLiteral UNO_NAME_TEXT_HORZADJUST
#define UNO_NAME_SIZE_TYPE
Definition: unoprnms.hxx:264
#define UNO_NAME_HORI_ORIENT
Definition: unoprnms.hxx:266
#define UNO_NAME_ANCHOR_PAGE_NO
Definition: unoprnms.hxx:233
constexpr OUStringLiteral UNO_NAME_TEXT_WORDWRAP
constexpr OUStringLiteral UNO_NAME_TEXT_VERTADJUST
#define UNO_NAME_PARA_ADJUST
Definition: unoprnms.hxx:176
constexpr OUStringLiteral UNO_NAME_TEXT_LEFTDIST
constexpr OUStringLiteral UNO_NAME_TEXT_WRITINGMODE
#define UNO_NAME_BOTTOM_BORDER
Definition: unoprnms.hxx:362
constexpr OUStringLiteral UNO_NAME_TEXT_AUTOGROWHEIGHT
#define UNO_NAME_LEFT_BORDER_DISTANCE
Definition: unoprnms.hxx:364
#define UNO_NAME_ANCHOR_TYPE
Definition: unoprnms.hxx:231
#define UNO_NAME_RIGHT_BORDER_DISTANCE
Definition: unoprnms.hxx:365
#define UNO_NAME_RELATIVE_HEIGHT_RELATION
Definition: unoprnms.hxx:196
#define UNO_NAME_ALLOW_OVERLAP
Definition: unoprnms.hxx:872
#define UNO_NAME_TOP_BORDER
Definition: unoprnms.hxx:361
#define UNO_NAME_CHAIN_NEXT_NAME
Definition: unoprnms.hxx:237
constexpr OUStringLiteral UNO_NAME_TEXT_RIGHTDIST
#define UNO_NAME_OPAQUE
Definition: unoprnms.hxx:288
#define UNO_NAME_IS_FOLLOWING_TEXT_FLOW
Definition: unoprnms.hxx:746
#define UNO_NAME_VERT_ORIENT
Definition: unoprnms.hxx:335
#define UNO_NAME_WRITING_MODE
Definition: unoprnms.hxx:696