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{
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 for (const sw::SpzFrameFormat* pFormat : *rDoc.GetSpzFrameFormats())
353 {
354 if (isTextBox(pFormat, RES_FLYFRMFMT))
355 ++nRet;
356 }
357 return nRet;
358}
359
360uno::Any SwTextBoxHelper::getByIndex(SdrPage const* pPage, sal_Int32 nIndex)
361{
362 if (nIndex < 0)
363 throw lang::IndexOutOfBoundsException();
364
365 SdrObject* pRet = nullptr;
366 sal_Int32 nCount = 0; // Current logical index.
367 for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
368 {
369 SdrObject* p = pPage->GetObj(i);
370 if (p && p->IsTextBox())
371 continue;
372 if (nCount == nIndex)
373 {
374 pRet = p;
375 break;
376 }
377 ++nCount;
378 }
379
380 if (!pRet)
381 throw lang::IndexOutOfBoundsException();
382
383 return uno::Any(uno::Reference<drawing::XShape>(pRet->getUnoShape(), uno::UNO_QUERY));
384}
385
386sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject)
387{
388 if (const SdrPage* pPage = pObject->getSdrPageFromSdrObject())
389 {
390 sal_Int32 nOrder = 0; // Current logical order.
391 for (std::size_t i = 0; i < pPage->GetObjCount(); ++i)
392 {
393 SdrObject* p = pPage->GetObj(i);
394 if (p && p->IsTextBox())
395 continue;
396 if (p == pObject)
397 return nOrder;
398 ++nOrder;
399 }
400 }
401
402 SAL_WARN("sw.core", "SwTextBoxHelper::getOrdNum: no page or page doesn't contain the object");
403 return pObject->GetOrdNum();
404}
405
406void SwTextBoxHelper::getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& rWrapThrough)
407{
409 if (pShape)
410 rWrapThrough = pShape->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH;
411}
412
414 sal_uInt16 nType, const SdrObject* pObject)
415{
416 SolarMutexGuard aGuard;
417 if (!isTextBox(pFormat, nType, pObject))
418 return nullptr;
419
420 if (nType == RES_DRAWFRMFMT)
421 {
422 if (pObject)
423 return pFormat->GetOtherTextBoxFormats()->GetTextBox(pObject);
424 if (pFormat->FindRealSdrObject())
425 return pFormat->GetOtherTextBoxFormats()->GetTextBox(pFormat->FindRealSdrObject());
426 return nullptr;
427 }
428 if (nType == RES_FLYFRMFMT)
429 {
430 return pFormat->GetOtherTextBoxFormats()->GetOwnerShape();
431 }
432 return nullptr;
433}
434
435SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XShape> const& xShape)
436{
437 auto pShape = dynamic_cast<SwXShape*>(xShape.get());
438 if (!pShape)
439 return nullptr;
440
441 SwFrameFormat* pFormat = pShape->GetFrameFormat();
444}
445
446uno::Reference<text::XTextFrame>
447SwTextBoxHelper::getUnoTextFrame(uno::Reference<drawing::XShape> const& xShape)
448{
449 if (xShape)
450 {
451 auto pFrameFormat = SwTextBoxHelper::getOtherTextBoxFormat(xShape);
452 if (pFrameFormat)
453 {
454 auto pSdrObj = pFrameFormat->FindSdrObject();
455 if (pSdrObj)
456 {
457 return { pSdrObj->getUnoShape(), uno::UNO_QUERY };
458 }
459 }
460 }
461 return {};
462}
463
464template <typename T>
465static void lcl_queryInterface(const SwFrameFormat* pShape, uno::Any& rAny, SdrObject* pObj)
466{
467 if (SwFrameFormat* pFormat
469 {
470 uno::Reference<T> const xInterface(
471 static_cast<cppu::OWeakObject*>(
472 SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat).get()),
473 uno::UNO_QUERY);
474 rAny <<= xInterface;
475 }
476}
477
479 SdrObject* pObj)
480{
481 uno::Any aRet;
482
484 {
485 lcl_queryInterface<text::XTextAppend>(pShape, aRet, pObj);
486 }
487 else if (rType == cppu::UnoType<css::text::XText>::get())
488 {
489 lcl_queryInterface<text::XText>(pShape, aRet, pObj);
490 }
492 {
493 lcl_queryInterface<text::XTextRange>(pShape, aRet, pObj);
494 }
495
496 return aRet;
497}
498
500{
501 tools::Rectangle aRet;
502 aRet.SetEmpty();
503
504 assert(pShape);
505
506 auto pCustomShape = dynamic_cast<SdrObjCustomShape*>(pShape);
507 if (pCustomShape)
508 {
509 // Need to temporarily release the lock acquired in
510 // SdXMLShapeContext::AddShape(), otherwise we get an empty rectangle,
511 // see EnhancedCustomShapeEngine::getTextBounds().
512 uno::Reference<document::XActionLockable> xLockable(pCustomShape->getUnoShape(),
513 uno::UNO_QUERY);
514 sal_Int16 nLocks = 0;
515 if (xLockable.is())
516 nLocks = xLockable->resetActionLocks();
517 pCustomShape->GetTextBounds(aRet);
518 if (nLocks)
519 xLockable->setActionLocks(nLocks);
520 }
521 else if (pShape)
522 {
523 // fallback - get *any* bound rect we can possibly get hold of
524 aRet = pShape->GetCurrentBoundRect();
525 }
526
527 if (pShape)
528 {
529 // Relative, so count the logic (reference) rectangle, see the EnhancedCustomShape2d ctor.
530 Point aPoint(pShape->GetSnapRect().Center());
531 Size aSize(pShape->GetLogicRect().GetSize());
532 aPoint.AdjustX(-(aSize.Width() / 2));
533 aPoint.AdjustY(-(aSize.Height() / 2));
534 tools::Rectangle aLogicRect(aPoint, aSize);
535 aRet.Move(-1 * aLogicRect.Left(), -1 * aLogicRect.Top());
536 }
537
538 return aRet;
539}
540
541void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, std::u16string_view rPropertyName,
542 const css::uno::Any& rValue, SdrObject* pObj)
543{
544 // Textframes does not have valid horizontal adjust property, so map it to paragraph adjust property
545 if (rPropertyName == UNO_NAME_TEXT_HORZADJUST)
546 {
547 SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
548 if (!pFormat)
549 return;
550
551 auto xTextFrame = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
552 uno::Reference<text::XTextCursor> xCursor = xTextFrame->getText()->createTextCursor();
553
554 // Select all paragraphs in the textframe
555 xCursor->gotoStart(false);
556 xCursor->gotoEnd(true);
557 uno::Reference<beans::XPropertySet> xFrameParaProps(xCursor, uno::UNO_QUERY);
558
559 // And simply map the property
560 const auto eValue = rValue.get<drawing::TextHorizontalAdjust>();
561 switch (eValue)
562 {
563 case drawing::TextHorizontalAdjust::TextHorizontalAdjust_CENTER:
564 xFrameParaProps->setPropertyValue(
566 uno::Any(style::ParagraphAdjust::ParagraphAdjust_CENTER)); //3
567 break;
568 case drawing::TextHorizontalAdjust::TextHorizontalAdjust_LEFT:
569 xFrameParaProps->setPropertyValue(
571 uno::Any(style::ParagraphAdjust::ParagraphAdjust_LEFT)); //0
572 break;
573 case drawing::TextHorizontalAdjust::TextHorizontalAdjust_RIGHT:
574 xFrameParaProps->setPropertyValue(
576 uno::Any(style::ParagraphAdjust::ParagraphAdjust_RIGHT)); //1
577 break;
578 default:
579 SAL_WARN("sw.core",
580 "SwTextBoxHelper::syncProperty: unhandled TextHorizontalAdjust: "
581 << static_cast<sal_Int32>(eValue));
582 break;
583 }
584 return;
585 }
586
587 if (rPropertyName == u"CustomShapeGeometry")
588 {
589 // CustomShapeGeometry changes the textbox position offset and size, so adjust both.
591
592 SdrObject* pObject = pObj ? pObj : pShape->FindRealSdrObject();
593 if (pObject)
594 {
595 tools::Rectangle aRectangle(pObject->GetSnapRect());
597 uno::Any(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Left()))));
599 uno::Any(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top()))));
600 }
601
602 SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
603 if (!pFormat)
604 return;
605
606 // Older documents or documents in ODF strict do not have WritingMode, but have used the
607 // TextRotateAngle values -90 and -270 to emulate these text directions of frames.
608 // ToDo: Is TextPreRotateAngle needed for diagrams or can it be removed?
609 comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue);
610 auto it = aCustomShapeGeometry.find("TextPreRotateAngle");
611 if (it == aCustomShapeGeometry.end())
612 {
613 it = aCustomShapeGeometry.find("TextRotateAngle");
614 }
615
616 if (it != aCustomShapeGeometry.end())
617 {
618 auto nAngle = it->second.has<sal_Int32>() ? it->second.get<sal_Int32>() : 0;
619 if (nAngle == 0)
620 {
621 nAngle = it->second.has<double>() ? it->second.get<double>() : 0;
622 }
623
624 sal_Int16 nDirection = 0;
625 switch (nAngle)
626 {
627 case -90:
628 nDirection = text::WritingMode2::TB_RL90;
629 break;
630 case -270:
631 nDirection = text::WritingMode2::BT_LR;
632 break;
633 default:
634 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled property value: "
635 "CustomShapeGeometry:TextPreRotateAngle: "
636 << nAngle);
637 break;
638 }
639
640 if (nDirection)
641 {
642 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(nDirection), pObj);
643 }
644 }
645 }
646 else if (rPropertyName == UNO_NAME_TEXT_VERT_ADJUST)
647 syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0, rValue, pObj);
648 else if (rPropertyName == UNO_NAME_TEXT_AUTOGROWHEIGHT)
650 else if (rPropertyName == UNO_NAME_TEXT_LEFTDIST)
651 syncProperty(pShape, RES_BOX, LEFT_BORDER_DISTANCE, rValue, pObj);
652 else if (rPropertyName == UNO_NAME_TEXT_RIGHTDIST)
653 syncProperty(pShape, RES_BOX, RIGHT_BORDER_DISTANCE, rValue, pObj);
654 else if (rPropertyName == UNO_NAME_TEXT_UPPERDIST)
655 syncProperty(pShape, RES_BOX, TOP_BORDER_DISTANCE, rValue, pObj);
656 else if (rPropertyName == UNO_NAME_TEXT_LOWERDIST)
657 syncProperty(pShape, RES_BOX, BOTTOM_BORDER_DISTANCE, rValue, pObj);
658 else if (rPropertyName == UNO_NAME_TEXT_WRITINGMODE)
659 {
660 text::WritingMode eMode;
661 sal_Int16 eMode2;
662 if (rValue >>= eMode)
663 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(sal_Int16(eMode)), pObj);
664 else if (rValue >>= eMode2)
665 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(eMode2), pObj);
666 }
667 else if (rPropertyName == u"WritingMode")
668 {
669 sal_Int16 eMode2;
670 if (rValue >>= eMode2)
671 syncProperty(pShape, RES_FRAMEDIR, 0, uno::Any(eMode2), pObj);
672 }
673 else
674 SAL_INFO("sw.core", "SwTextBoxHelper::syncProperty: unhandled property: "
675 << static_cast<OUString>(rPropertyName));
676}
677
678void SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
679 css::uno::Any& rValue)
680{
681 if (!pShape)
682 return;
683
684 nMemberID &= ~CONVERT_TWIPS;
685
687 if (!pFormat)
688 return;
689
690 if (nWID != RES_CHAIN)
691 return;
692
693 switch (nMemberID)
694 {
697 {
698 const SwFormatChain& rChain = pFormat->GetChain();
699 rChain.QueryValue(rValue, nMemberID);
700 }
701 break;
702 case MID_CHAIN_NAME:
703 rValue <<= pFormat->GetName();
704 break;
705 default:
706 SAL_WARN("sw.core", "SwTextBoxHelper::getProperty: unhandled member-id: "
707 << o3tl::narrowing<sal_uInt16>(nMemberID));
708 break;
709 }
710}
711
712css::uno::Any SwTextBoxHelper::getProperty(SwFrameFormat const* pShape, const OUString& rPropName)
713{
714 if (!pShape)
715 return {};
716
718 if (!pFormat)
719 return {};
720
722 = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
723
724 return xPropertySet->getPropertyValue(rPropName);
725}
726
727void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID,
728 const css::uno::Any& rValue, SdrObject* pObj)
729{
730 // No shape yet? Then nothing to do, initial properties are set by create().
731 if (!pShape)
732 return;
733
734 uno::Any aValue(rValue);
735 nMemberID &= ~CONVERT_TWIPS;
736
737 SwFrameFormat* pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
738 if (!pFormat)
739 return;
740
741 OUString aPropertyName;
742 bool bAdjustX = false;
743 bool bAdjustY = false;
744 bool bAdjustSize = false;
745 switch (nWID)
746 {
747 case RES_HORI_ORIENT:
748 switch (nMemberID)
749 {
751 aPropertyName = UNO_NAME_HORI_ORIENT;
752 break;
754 if (pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)
755 aPropertyName = UNO_NAME_HORI_ORIENT_RELATION;
756 else
757 return;
758 break;
760 aPropertyName = UNO_NAME_HORI_ORIENT_POSITION;
761 bAdjustX = true;
762 break;
763 default:
764 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
765 << o3tl::narrowing<sal_uInt16>(nMemberID)
766 << " (which-id: " << nWID << ")");
767 break;
768 }
769 break;
770 case RES_LR_SPACE:
771 {
772 switch (nMemberID)
773 {
774 case MID_L_MARGIN:
775 aPropertyName = UNO_NAME_LEFT_MARGIN;
776 break;
777 case MID_R_MARGIN:
778 aPropertyName = UNO_NAME_RIGHT_MARGIN;
779 break;
780 default:
781 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
782 << o3tl::narrowing<sal_uInt16>(nMemberID)
783 << " (which-id: " << nWID << ")");
784 break;
785 }
786 break;
787 }
788 case RES_VERT_ORIENT:
789 switch (nMemberID)
790 {
792 aPropertyName = UNO_NAME_VERT_ORIENT;
793 break;
795 if (pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)
796 aPropertyName = UNO_NAME_VERT_ORIENT_RELATION;
797 else
798 return;
799 break;
801 aPropertyName = UNO_NAME_VERT_ORIENT_POSITION;
802 bAdjustY = true;
803 break;
804 default:
805 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
806 << o3tl::narrowing<sal_uInt16>(nMemberID)
807 << " (which-id: " << nWID << ")");
808 break;
809 }
810 break;
811 case RES_FRM_SIZE:
812 switch (nMemberID)
813 {
815 aPropertyName = UNO_NAME_WIDTH_TYPE;
816 break;
818 aPropertyName = UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT;
819 break;
821 aPropertyName = UNO_NAME_RELATIVE_HEIGHT_RELATION;
822 break;
824 aPropertyName = UNO_NAME_RELATIVE_WIDTH_RELATION;
825 break;
826 default:
827 aPropertyName = UNO_NAME_SIZE;
828 bAdjustSize = true;
829 break;
830 }
831 break;
832 case RES_ANCHOR:
833 switch (nMemberID)
834 {
836 {
837 changeAnchor(pShape, pObj);
838 return;
839 }
840 break;
841 default:
842 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
843 << o3tl::narrowing<sal_uInt16>(nMemberID)
844 << " (which-id: " << nWID << ")");
845 break;
846 }
847 break;
848 case FN_TEXT_RANGE:
849 {
850 uno::Reference<text::XTextRange> xRange;
851 rValue >>= xRange;
852 SwUnoInternalPaM aInternalPaM(*pFormat->GetDoc());
853 if (sw::XTextRangeToSwPaM(aInternalPaM, xRange))
854 {
855 SwFormatAnchor aAnchor(pFormat->GetAnchor());
856 aAnchor.SetAnchor(aInternalPaM.Start());
857 pFormat->SetFormatAttr(aAnchor);
858 }
859 }
860 break;
861 case RES_CHAIN:
862 switch (nMemberID)
863 {
865 aPropertyName = UNO_NAME_CHAIN_PREV_NAME;
866 break;
868 aPropertyName = UNO_NAME_CHAIN_NEXT_NAME;
869 break;
870 default:
871 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
872 << o3tl::narrowing<sal_uInt16>(nMemberID)
873 << " (which-id: " << nWID << ")");
874 break;
875 }
876 break;
878 aPropertyName = UNO_NAME_TEXT_VERT_ADJUST;
879 break;
880 case RES_BOX:
881 switch (nMemberID)
882 {
884 aPropertyName = UNO_NAME_LEFT_BORDER_DISTANCE;
885 break;
887 aPropertyName = UNO_NAME_RIGHT_BORDER_DISTANCE;
888 break;
890 aPropertyName = UNO_NAME_TOP_BORDER_DISTANCE;
891 break;
893 aPropertyName = UNO_NAME_BOTTOM_BORDER_DISTANCE;
894 break;
895 default:
896 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
897 << o3tl::narrowing<sal_uInt16>(nMemberID)
898 << " (which-id: " << nWID << ")");
899 break;
900 }
901 break;
902 case RES_OPAQUE:
903 aPropertyName = UNO_NAME_OPAQUE;
904 break;
905 case RES_FRAMEDIR:
906 aPropertyName = UNO_NAME_WRITING_MODE;
907 break;
909 switch (nMemberID)
910 {
912 aPropertyName = UNO_NAME_ALLOW_OVERLAP;
913 break;
914 default:
915 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled member-id: "
916 << o3tl::narrowing<sal_uInt16>(nMemberID)
917 << " (which-id: " << nWID << ")");
918 break;
919 }
920 break;
921 default:
922 SAL_WARN("sw.core", "SwTextBoxHelper::syncProperty: unhandled which-id: "
923 << nWID << " (member-id: "
924 << o3tl::narrowing<sal_uInt16>(nMemberID) << ")");
925 break;
926 }
927
928 if (aPropertyName.isEmpty())
929 return;
930
931 // Position/size should be the text position/size, not the shape one as-is.
932 if (bAdjustX || bAdjustY || bAdjustSize)
933 {
934 changeAnchor(pShape, pObj);
935 tools::Rectangle aRect
936 = getRelativeTextRectangle(pObj ? pObj : pShape->FindRealSdrObject());
937 if (!aRect.IsEmpty())
938 {
939 if (bAdjustX || bAdjustY)
940 {
941 sal_Int32 nValue;
942 if (aValue >>= nValue)
943 {
944 nValue += convertTwipToMm100(bAdjustX ? aRect.Left() : aRect.Top());
945 aValue <<= nValue;
946 }
947 }
948 else if (bAdjustSize)
949 {
950 awt::Size aSize(convertTwipToMm100(aRect.getOpenWidth()),
952 aValue <<= aSize;
953 }
954 }
955 }
956 auto aGuard = SwTextBoxLockGuard(*pShape->GetOtherTextBoxFormats());
957 rtl::Reference<SwXTextFrame> const xPropertySet
958 = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
959 xPropertySet->setPropertyValue(aPropertyName, aValue);
960}
961
963 std::map<const SwFrameFormat*, const SwFrameFormat*>& rLinks)
964{
965 for (const auto pFormat : rFormats)
966 {
967 if (SwFrameFormat* pTextBox = getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
968 rLinks[pFormat] = pTextBox;
969 }
970}
971
972void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrameFormat*>& rNew,
973 SavedLink& rSavedLinks)
974{
975 std::size_t i = 0;
976 for (const auto& rIt : rOld)
977 {
978 auto aTextBoxIt = rSavedLinks.find(rIt.GetFormat());
979 if (aTextBoxIt != rSavedLinks.end())
980 {
981 std::size_t j = 0;
982 for (const auto& rJt : rOld)
983 {
984 if (rJt.GetFormat() == aTextBoxIt->second)
985 rNew[i]->SetFormatAttr(rNew[j]->GetContent());
986 ++j;
987 }
988 }
989 ++i;
990 }
991}
992
993text::TextContentAnchorType SwTextBoxHelper::mapAnchorType(const RndStdIds& rAnchorID)
994{
995 text::TextContentAnchorType aAnchorType;
996 switch (rAnchorID)
997 {
998 case RndStdIds::FLY_AS_CHAR:
999 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AS_CHARACTER;
1000 break;
1001 case RndStdIds::FLY_AT_CHAR:
1002 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_CHARACTER;
1003 break;
1004 case RndStdIds::FLY_AT_PARA:
1005 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH;
1006 break;
1007 case RndStdIds::FLY_AT_PAGE:
1008 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PAGE;
1009 break;
1010 case RndStdIds::FLY_AT_FLY:
1011 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_FRAME;
1012 break;
1013 default:
1014 aAnchorType = text::TextContentAnchorType::TextContentAnchorType_AT_PARAGRAPH;
1015 SAL_WARN("sw.core", "SwTextBoxHelper::mapAnchorType: Unknown AnchorType!");
1016 break;
1017 }
1018 return aAnchorType;
1019}
1020
1022 SdrObject* pObj)
1023{
1024 SwFrameFormat* pFormat = getOtherTextBoxFormat(&rShape, RES_DRAWFRMFMT, pObj);
1025 if (!pFormat)
1026 return;
1027
1028 const bool bInlineAnchored = rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR;
1029 const bool bLayoutInCell = rShape.GetFollowTextFlow().GetValue()
1030 && rShape.GetAnchor().GetAnchorNode()
1031 && rShape.GetAnchor().GetAnchorNode()->FindTableNode();
1032 SfxItemSet aTextBoxSet(pFormat->GetDoc()->GetAttrPool(), aFrameFormatSetRange);
1033
1034 SfxItemIter aIter(rSet);
1035 const SfxPoolItem* pItem = aIter.GetCurItem();
1036
1037 do
1038 {
1039 switch (pItem->Which())
1040 {
1041 case RES_VERT_ORIENT:
1042 {
1043 // The new position can be with anchor changing so sync it!
1044 const text::TextContentAnchorType aNewAnchorType
1045 = mapAnchorType(rShape.GetAnchor().GetAnchorId());
1046 syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType),
1047 pObj);
1048 if (bInlineAnchored || bLayoutInCell)
1049 return;
1051
1052 tools::Rectangle aRect
1053 = getRelativeTextRectangle(pObj ? pObj : rShape.FindRealSdrObject());
1054 if (!aRect.IsEmpty())
1055 aOrient.SetPos(aOrient.GetPos() + aRect.Top());
1056
1057 if (rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
1058 && rShape.GetAnchor().GetPageNum() != 0)
1060 aTextBoxSet.Put(aOrient);
1061
1062 // restore height (shrunk for extending beyond the page bottom - tdf#91260)
1063 SwFormatFrameSize aSize(pFormat->GetFrameSize());
1064 if (!aRect.IsEmpty())
1065 {
1066 aSize.SetHeight(aRect.getOpenHeight());
1067 aTextBoxSet.Put(aSize);
1068 }
1069 }
1070 break;
1071 case RES_HORI_ORIENT:
1072 {
1073 // The new position can be with anchor changing so sync it!
1074 const text::TextContentAnchorType aNewAnchorType
1075 = mapAnchorType(rShape.GetAnchor().GetAnchorId());
1076 syncProperty(&rShape, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE, uno::Any(aNewAnchorType),
1077 pObj);
1078 if (bInlineAnchored || bLayoutInCell)
1079 return;
1081
1082 tools::Rectangle aRect
1083 = getRelativeTextRectangle(pObj ? pObj : rShape.FindRealSdrObject());
1084 if (!aRect.IsEmpty())
1085 aOrient.SetPos(aOrient.GetPos() + aRect.Left());
1086
1087 if (rShape.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
1088 && rShape.GetAnchor().GetPageNum() != 0)
1090 aTextBoxSet.Put(aOrient);
1091 }
1092 break;
1093 case RES_FRM_SIZE:
1094 {
1095 // In case the shape got resized, then we need to adjust both
1096 // the position and the size of the textbox (e.g. larger
1097 // rounded edges of a rectangle -> need to push right/down the
1098 // textbox).
1099 SwFormatVertOrient aVertOrient(rShape.GetVertOrient());
1100 SwFormatHoriOrient aHoriOrient(rShape.GetHoriOrient());
1101 SwFormatFrameSize aSize(pFormat->GetFrameSize());
1102
1103 tools::Rectangle aRect
1104 = getRelativeTextRectangle(pObj ? pObj : rShape.FindRealSdrObject());
1105 if (!aRect.IsEmpty())
1106 {
1107 if (!bInlineAnchored)
1108 {
1109 aVertOrient.SetPos(
1110 (pObj ? pObj->GetRelativePos().getX() : aVertOrient.GetPos())
1111 + aRect.Top());
1112 aHoriOrient.SetPos(
1113 (pObj ? pObj->GetRelativePos().getY() : aHoriOrient.GetPos())
1114 + aRect.Left());
1115
1116 aTextBoxSet.Put(aVertOrient);
1117 aTextBoxSet.Put(aHoriOrient);
1118 }
1119
1120 aSize.SetWidth(aRect.getOpenWidth());
1121 aSize.SetHeight(aRect.getOpenHeight());
1122 aTextBoxSet.Put(aSize);
1123 }
1124 }
1125 break;
1126 case RES_ANCHOR:
1127 {
1128 if (pItem->StaticWhichCast(RES_ANCHOR) == rShape.GetAnchor())
1129 // the anchor have to be synced
1130 {
1131 const text::TextContentAnchorType aNewAnchorType
1132 = mapAnchorType(rShape.GetAnchor().GetAnchorId());
1134 uno::Any(aNewAnchorType), pObj);
1135 }
1136 else
1137 {
1138 SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrameAttr: The anchor of the "
1139 "shape different from the textframe!");
1140 }
1141 }
1142 break;
1143 default:
1144 SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrameAttr: unhandled which-id: "
1145 << pItem->Which());
1146 break;
1147 }
1148
1149 pItem = aIter.NextItem();
1150 } while (pItem && (0 != pItem->Which()));
1151
1152 if (aTextBoxSet.Count())
1153 {
1154 auto aGuard = SwTextBoxLockGuard(*rShape.GetOtherTextBoxFormats());
1155 pFormat->SetFormatAttr(aTextBoxSet);
1156 }
1157 DoTextBoxZOrderCorrection(&rShape, pObj);
1158}
1159
1161{
1162 if (!pObj)
1163 return;
1164 uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY);
1165 if (!xShape)
1166 return;
1167 uno::Reference<beans::XPropertySet> const xPropertySet(xShape, uno::UNO_QUERY);
1168
1169 auto pParentFormat = getOtherTextBoxFormat(getOtherTextBoxFormat(xShape), RES_FLYFRMFMT);
1170 if (!pParentFormat)
1171 return;
1172
1173 // Sync the padding
1174 syncProperty(pParentFormat, UNO_NAME_TEXT_LEFTDIST,
1175 xPropertySet->getPropertyValue(UNO_NAME_TEXT_LEFTDIST), pObj);
1177 xPropertySet->getPropertyValue(UNO_NAME_TEXT_RIGHTDIST), pObj);
1179 xPropertySet->getPropertyValue(UNO_NAME_TEXT_UPPERDIST), pObj);
1181 xPropertySet->getPropertyValue(UNO_NAME_TEXT_LOWERDIST), pObj);
1182
1183 // Sync the text aligning
1185 xPropertySet->getPropertyValue(UNO_NAME_TEXT_VERTADJUST), pObj);
1187 xPropertySet->getPropertyValue(UNO_NAME_TEXT_HORZADJUST), pObj);
1188
1189 // tdf137803: Sync autogrow:
1190 const bool bIsAutoGrow
1191 = xPropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT).get<bool>();
1192 const bool bIsAutoWrap = xPropertySet->getPropertyValue(UNO_NAME_TEXT_WORDWRAP).get<bool>();
1193
1194 syncProperty(pParentFormat, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, uno::Any(bIsAutoGrow),
1195 pObj);
1196
1198 uno::Any(bIsAutoWrap ? text::SizeType::FIX : text::SizeType::MIN), pObj);
1199
1200 changeAnchor(pParentFormat, pObj);
1201 DoTextBoxZOrderCorrection(pParentFormat, pObj);
1202}
1203
1205{
1206 if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
1207 {
1208 if (!isAnchorSyncNeeded(pShape, pFormat))
1209 {
1210 doTextBoxPositioning(pShape, pObj);
1211 DoTextBoxZOrderCorrection(pShape, pObj);
1212 if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR
1213 && pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR
1214 && pFormat->GetVertOrient().GetRelationOrient() != text::RelOrientation::PRINT_AREA)
1215 {
1216 SwFormatVertOrient aTmp = pFormat->GetVertOrient();
1217 aTmp.SetRelationOrient(text::RelOrientation::PRINT_AREA);
1218 pFormat->SetFormatAttr(aTmp);
1219 }
1220
1221 return false;
1222 }
1223
1224 const SwFormatAnchor& rOldAnch = pFormat->GetAnchor();
1225 const SwFormatAnchor& rNewAnch = pShape->GetAnchor();
1226
1227 const auto pOldCnt = rOldAnch.GetContentAnchor();
1228 const auto pNewCnt = rNewAnch.GetContentAnchor();
1229
1230 const uno::Any aShapeHorRelOrient(pShape->GetHoriOrient().GetRelationOrient());
1231
1232 try
1233 {
1234 auto aGuard = SwTextBoxLockGuard(*pShape->GetOtherTextBoxFormats());
1235 ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
1236 rtl::Reference<SwXTextFrame> const xPropertySet
1237 = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
1238 if (pOldCnt && rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
1239 && rNewAnch.GetPageNum())
1240 {
1241 uno::Any aValue(text::TextContentAnchorType_AT_PAGE);
1242 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION, aShapeHorRelOrient);
1243 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1244 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO,
1245 uno::Any(rNewAnch.GetPageNum()));
1246 }
1247 else if (rOldAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE && pNewCnt)
1248 {
1249 if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1250 {
1251 assert(pNewCnt);
1252 uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
1253 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1254 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1255 uno::Any(text::RelOrientation::CHAR));
1256 xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
1257 uno::Any(text::RelOrientation::PRINT_AREA));
1258 SwFormatAnchor aPos(pFormat->GetAnchor());
1259 aPos.SetAnchor(pNewCnt);
1260 pFormat->SetFormatAttr(aPos);
1261 }
1262 else
1263 {
1264 uno::Any aValue(mapAnchorType(rNewAnch.GetAnchorId()));
1265 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1266 aShapeHorRelOrient);
1267 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1268 pFormat->SetFormatAttr(rNewAnch);
1269 }
1270 }
1271 else
1272 {
1273 if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1274 {
1275 assert(pNewCnt);
1276 uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
1277 xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
1278 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1279 uno::Any(text::RelOrientation::CHAR));
1280 xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
1281 uno::Any(text::RelOrientation::PRINT_AREA));
1282 SwFormatAnchor aPos(pFormat->GetAnchor());
1283 aPos.SetAnchor(pNewCnt);
1284 pFormat->SetFormatAttr(aPos);
1285 }
1286 else
1287 {
1288 xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
1289 aShapeHorRelOrient);
1290 if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
1291 && rNewAnch.GetPageNum() == 0)
1292 {
1293 pFormat->SetFormatAttr(SwFormatAnchor(RndStdIds::FLY_AT_PAGE, 1));
1294 }
1295 else
1296 pFormat->SetFormatAttr(pShape->GetAnchor());
1297 }
1298 }
1299 }
1300 catch (uno::Exception& e)
1301 {
1302 SAL_WARN("sw.core", "SwTextBoxHelper::changeAnchor(): " << e.Message);
1303 }
1304
1305 doTextBoxPositioning(pShape, pObj);
1306 DoTextBoxZOrderCorrection(pShape, pObj);
1307 return true;
1308 }
1309
1310 return false;
1311}
1312
1314{
1315 // Set the position of the textboxes according to the position of its shape-pair
1316 const bool bIsGroupObj = (pObj != pShape->FindRealSdrObject()) && pObj;
1317 if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
1318 {
1319 // Do not create undo entry for the positioning
1320 ::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
1321 auto aGuard = SwTextBoxLockGuard(*pShape->GetOtherTextBoxFormats());
1322 // Special treatment for AS_CHAR textboxes:
1323 if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1324 {
1325 // Get the text area of the shape
1326 tools::Rectangle aRect
1327 = getRelativeTextRectangle(pObj ? pObj : pShape->FindRealSdrObject());
1328
1329 // Get the left spacing of the text area of the shape
1330 auto nLeftSpace = pShape->GetLRSpace().GetLeft();
1331
1332 // Set the textbox position at the X-axis:
1333 SwFormatHoriOrient aNewHOri(pFormat->GetHoriOrient());
1334 if (bIsGroupObj && aNewHOri.GetHoriOrient() != text::HoriOrientation::NONE)
1336 aNewHOri.SetPos(aRect.Left() + nLeftSpace
1337 + (bIsGroupObj ? pObj->GetRelativePos().getX() : 0));
1338 SwFormatVertOrient aNewVOri(pFormat->GetVertOrient());
1339
1340 // Special handling of group textboxes
1341 if (bIsGroupObj)
1342 {
1343 // There are the following cases:
1344 // case 1: The textbox should be in that position where the shape is.
1345 // case 2: The shape has negative offset so that have to be subtracted
1346 // case 3: The shape and its parent shape also has negative offset, so subtract
1347 aNewVOri.SetPos(
1348 ((pObj->GetRelativePos().getY()) > 0
1349 ? (pShape->GetVertOrient().GetPos() > 0
1350 ? pObj->GetRelativePos().getY()
1351 : pObj->GetRelativePos().getY() - pShape->GetVertOrient().GetPos())
1352 : (pShape->GetVertOrient().GetPos() > 0
1353 ? 0 // Is this can be a variation?
1354 : pObj->GetRelativePos().getY() - pShape->GetVertOrient().GetPos()))
1355 + aRect.Top());
1356 }
1357 else
1358 {
1359 // Simple textboxes: vertical position equals to the vertical offset of the shape
1360 aNewVOri.SetPos(
1361 ((pShape->GetVertOrient().GetPos()) > 0 ? pShape->GetVertOrient().GetPos() : 0)
1362 + aRect.Top());
1363 }
1364
1365 // Special cases when the shape is aligned to the line
1367 {
1369 switch (pShape->GetVertOrient().GetVertOrient())
1370 {
1371 // Top aligned shape
1372 case text::VertOrientation::TOP:
1373 case text::VertOrientation::CHAR_TOP:
1374 case text::VertOrientation::LINE_TOP:
1375 {
1376 aNewVOri.SetPos(aNewVOri.GetPos() - pShape->GetFrameSize().GetHeight());
1377 break;
1378 }
1379 // Bottom aligned shape
1380 case text::VertOrientation::BOTTOM:
1381 case text::VertOrientation::CHAR_BOTTOM:
1382 case text::VertOrientation::LINE_BOTTOM:
1383 {
1384 aNewVOri.SetPos(aNewVOri.GetPos() + pShape->GetFrameSize().GetHeight());
1385 break;
1386 }
1387 // Center aligned shape
1388 case text::VertOrientation::CENTER:
1389 case text::VertOrientation::CHAR_CENTER:
1390 case text::VertOrientation::LINE_CENTER:
1391 {
1392 aNewVOri.SetPos(aNewVOri.GetPos()
1393 + std::lroundf(pShape->GetFrameSize().GetHeight() / 2));
1394 break;
1395 }
1396 default:
1397 break;
1398 }
1399 }
1400
1401 pFormat->SetFormatAttr(aNewHOri);
1402 pFormat->SetFormatAttr(aNewVOri);
1403 }
1404 // Other cases when the shape has different anchor from AS_CHAR
1405 else
1406 {
1407 // Text area of the shape
1408 tools::Rectangle aRect
1409 = getRelativeTextRectangle(pObj ? pObj : pShape->FindRealSdrObject());
1410
1411 // X Offset of the shape spacing
1412 auto nLeftSpace = pShape->GetLRSpace().GetLeft();
1413
1414 // Set the same position as the (child) shape has
1415 SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
1416 if (bIsGroupObj && aNewHOri.GetHoriOrient() != text::HoriOrientation::NONE)
1418
1419 aNewHOri.SetPos(
1420 (bIsGroupObj && pObj ? pObj->GetRelativePos().getX() : aNewHOri.GetPos())
1421 + aRect.Left());
1422 SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
1423 aNewVOri.SetPos(
1424 (bIsGroupObj && pObj ? pObj->GetRelativePos().getY() : aNewVOri.GetPos())
1425 + aRect.Top());
1426
1427 // Get the distance of the child shape inside its parent
1428 const auto& nInshapePos
1429 = pObj ? pObj->GetRelativePos() - pShape->FindRealSdrObject()->GetRelativePos()
1430 : Point();
1431
1432 // Special case: the shape has relative position from the page
1433 if (pShape->GetHoriOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME
1434 && pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AT_PAGE)
1435 {
1436 aNewHOri.SetRelationOrient(text::RelOrientation::PAGE_FRAME);
1437 aNewHOri.SetPos(pShape->GetHoriOrient().GetPos() + nInshapePos.getX()
1438 + aRect.Left());
1439 }
1440
1441 if (pShape->GetVertOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME
1442 && pShape->GetAnchor().GetAnchorId() != RndStdIds::FLY_AT_PAGE)
1443 {
1444 aNewVOri.SetRelationOrient(text::RelOrientation::PAGE_FRAME);
1445 aNewVOri.SetPos(pShape->GetVertOrient().GetPos() + nInshapePos.getY()
1446 + aRect.Top());
1447 }
1448
1449 // Other special case: shape is inside a table or floating table following the text flow
1450 if (pShape->GetFollowTextFlow().GetValue() && pShape->GetAnchor().GetAnchorNode()
1451 && pShape->GetAnchor().GetAnchorNode()->FindTableNode())
1452 {
1453 // Table position
1454 Point nTableOffset;
1455 // Floating table
1456 if (auto pFly
1458 {
1459 if (auto pFlyFormat = pFly->GetFlyFormat())
1460 {
1461 nTableOffset.setX(pFlyFormat->GetHoriOrient().GetPos());
1462 nTableOffset.setY(pFlyFormat->GetVertOrient().GetPos());
1463 }
1464 }
1465 else
1466 // Normal table
1467 {
1468 auto pTableNode = pShape->GetAnchor().GetAnchorNode()->FindTableNode();
1469 if (auto pTableFormat = pTableNode->GetTable().GetFrameFormat())
1470 {
1471 nTableOffset.setX(pTableFormat->GetHoriOrient().GetPos());
1472 nTableOffset.setY(pTableFormat->GetVertOrient().GetPos());
1473 }
1474 }
1475
1476 // Add the table positions to the textbox.
1477 aNewHOri.SetPos(aNewHOri.GetPos() + nTableOffset.getX() + nLeftSpace);
1478 if (pShape->GetVertOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME
1479 || pShape->GetVertOrient().GetRelationOrient()
1480 == text::RelOrientation::PAGE_PRINT_AREA)
1481 aNewVOri.SetPos(aNewVOri.GetPos() + nTableOffset.getY());
1482 }
1483
1484 pFormat->SetFormatAttr(aNewHOri);
1485 pFormat->SetFormatAttr(aNewVOri);
1486 }
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1494{
1495 if (!pShape || !pObj)
1496 return false;
1497
1498 if (auto pTextBox = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
1499 {
1500 auto aGuard = SwTextBoxLockGuard(*pShape->GetOtherTextBoxFormats());
1501 const auto& rSize = getRelativeTextRectangle(pObj).GetSize();
1502 if (!rSize.IsEmpty())
1503 {
1504 SwFormatFrameSize aSize(pTextBox->GetFrameSize());
1505 aSize.SetSize(rSize);
1506 return pTextBox->SetFormatAttr(aSize);
1507 }
1508 }
1509
1510 return false;
1511}
1512
1514{
1515 // TODO: do this with group shape textboxes.
1516 SdrObject* pShpObj = nullptr;
1517
1518 pShpObj = pShape->FindRealSdrObject();
1519
1520 if (pShpObj)
1521 {
1522 auto pTextBox = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
1523 if (!pTextBox)
1524 return false;
1525 SdrObject* pFrmObj = pTextBox->FindRealSdrObject();
1526 if (!pFrmObj)
1527 {
1528 // During loading there is no ready SdrObj for z-ordering, so create and cache it here
1529 pFrmObj
1530 = SwXTextFrame::GetOrCreateSdrObject(*dynamic_cast<SwFlyFrameFormat*>(pTextBox));
1531 }
1532 if (pFrmObj)
1533 {
1534 // Get the draw model from the doc
1535 SwDrawModel* pDrawModel
1537 if (pDrawModel)
1538 {
1539 // Not really sure this will work on all pages, but it seems it will.
1540 auto pPage = pDrawModel->GetPage(0);
1541 // Recalc all Z-orders
1542 pPage->RecalcObjOrdNums();
1543 // Here is a counter avoiding running to in infinity:
1544 sal_uInt16 nIterator = 0;
1545 // If the shape is behind the frame, is good, but if there are some objects
1546 // between of them that is wrong so put the frame exactly one level higher
1547 // than the shape.
1548 if (pFrmObj->GetOrdNum() > pShpObj->GetOrdNum())
1549 pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pShpObj->GetOrdNum() + 1);
1550 else
1551 // Else, if the frame is behind the shape, bring to the front of it.
1552 while (pFrmObj->GetOrdNum() <= pShpObj->GetOrdNum())
1553 {
1554 pPage->SetObjectOrdNum(pFrmObj->GetOrdNum(), pFrmObj->GetOrdNum() + 1);
1555 // If there is any problem with the indexes, do not run over the infinity
1556 if (pPage->GetObjCount() == pFrmObj->GetOrdNum())
1557 break;
1558 ++nIterator;
1559 if (nIterator > 300)
1560 break; // Do not run to infinity
1561 }
1562 pPage->RecalcObjOrdNums();
1563 return true; // Success
1564 }
1565 SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1566 "No Valid Draw model for SdrObject for the shape!");
1567 }
1568 SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1569 "No Valid SdrObject for the frame!");
1570 }
1571 SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
1572 "No Valid SdrObject for the shape!");
1573
1574 return false;
1575}
1576
1578 SwFrameFormat* pFormat, SdrObject* pObj)
1579{
1580 if (auto pChildren = pObj->getChildrenOfSdrObject())
1581 {
1582 for (size_t i = 0; i < pChildren->GetObjCount(); ++i)
1583 synchronizeGroupTextBoxProperty(pFunc, pFormat, pChildren->GetObj(i));
1584 }
1585 else
1586 {
1587 (*pFunc)(pFormat, pObj);
1588 }
1589}
1590
1591std::vector<SwFrameFormat*> SwTextBoxHelper::CollectTextBoxes(const SdrObject* pGroupObject,
1592 SwFrameFormat* pFormat)
1593{
1594 std::vector<SwFrameFormat*> vRet;
1595 if (auto pChildren = pGroupObject->getChildrenOfSdrObject())
1596 {
1597 for (size_t i = 0; i < pChildren->GetObjCount(); ++i)
1598 {
1599 auto pChildTextBoxes = CollectTextBoxes(pChildren->GetObj(i), pFormat);
1600 for (auto& rChildTextBox : pChildTextBoxes)
1601 vRet.push_back(rChildTextBox);
1602 }
1603 }
1604 else
1605 {
1606 if (isTextBox(pFormat, RES_DRAWFRMFMT, pGroupObject))
1607 vRet.push_back(getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT, pGroupObject));
1608 }
1609 return vRet;
1610}
1611
1613{
1614 if (!pFirst)
1615 return false;
1616
1617 if (!pSecond)
1618 return false;
1619
1620 if (pFirst == pSecond)
1621 return false;
1622
1623 if (!pFirst->GetOtherTextBoxFormats())
1624 return false;
1625
1626 if (!pSecond->GetOtherTextBoxFormats())
1627 return false;
1628
1629 if (pFirst->GetOtherTextBoxFormats() != pSecond->GetOtherTextBoxFormats())
1630 return false;
1631
1632 if (pFirst->GetOtherTextBoxFormats()->GetOwnerShape() == pSecond
1633 || pFirst == pSecond->GetOtherTextBoxFormats()->GetOwnerShape())
1634 {
1635 const auto& rShapeAnchor
1636 = pFirst->Which() == RES_DRAWFRMFMT ? pFirst->GetAnchor() : pSecond->GetAnchor();
1637 const auto& rFrameAnchor
1638 = pFirst->Which() == RES_FLYFRMFMT ? pFirst->GetAnchor() : pSecond->GetAnchor();
1639
1640 if (rShapeAnchor.GetAnchorId() == rFrameAnchor.GetAnchorId())
1641 {
1642 if (rShapeAnchor.GetAnchorNode() && rFrameAnchor.GetAnchorNode())
1643 {
1644 if (*rShapeAnchor.GetContentAnchor() != *rFrameAnchor.GetContentAnchor())
1645 return true;
1646
1647 return false;
1648 }
1649
1650 if (rShapeAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE
1651 && rFrameAnchor.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
1652 {
1653 if (rShapeAnchor.GetPageNum() == rFrameAnchor.GetPageNum())
1654 return false;
1655 else
1656 return true;
1657 }
1658
1659 return true;
1660 }
1661
1662 if (rShapeAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR
1663 && rFrameAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
1664 {
1665 if (rShapeAnchor.GetAnchorNode() && rFrameAnchor.GetAnchorNode())
1666 {
1667 if (*rShapeAnchor.GetContentAnchor() != *rFrameAnchor.GetContentAnchor())
1668 return true;
1669
1670 return false;
1671 }
1672 }
1673 return true;
1674 }
1675 return false;
1676}
1677
1679{
1680 assert(pOwnerShape);
1681 assert(pOwnerShape->Which() == RES_DRAWFRMFMT);
1682
1683 m_bIsCloningInProgress = false;
1684 m_bLock = false;
1685
1686 m_pOwnerShapeFormat = pOwnerShape;
1687 if (!m_pTextBoxes.empty())
1688 m_pTextBoxes.clear();
1689}
1690
1692{
1693 if (m_pTextBoxes.size() != 0)
1694 {
1695 SAL_WARN("sw.core", "SwTextBoxNode::~SwTextBoxNode(): Text-Box-Vector still not empty!");
1696 assert(false);
1697 }
1698}
1699
1700void SwTextBoxNode::AddTextBox(SdrObject* pDrawObject, SwFrameFormat* pNewTextBox)
1701{
1702 assert(pNewTextBox);
1703 assert(pNewTextBox->Which() == RES_FLYFRMFMT);
1704
1705 assert(pDrawObject);
1706
1707 SwTextBoxElement aElem;
1708 aElem.m_pDrawObject = pDrawObject;
1709 aElem.m_pTextBoxFormat = pNewTextBox;
1710
1711 for (const auto& rE : m_pTextBoxes)
1712 {
1713 if (rE.m_pDrawObject == pDrawObject || rE.m_pTextBoxFormat == pNewTextBox)
1714 {
1715 SAL_WARN("sw.core", "SwTextBoxNode::AddTextBox(): Already exist!");
1716 return;
1717 }
1718 }
1719
1720 auto pSwFlyDraw = dynamic_cast<SwFlyDrawObj*>(pDrawObject);
1721 if (pSwFlyDraw)
1722 {
1723 pSwFlyDraw->SetTextBox(true);
1724 }
1725 m_pTextBoxes.push_back(aElem);
1726}
1727
1728void SwTextBoxNode::DelTextBox(const SdrObject* pDrawObject, bool bDelFromDoc)
1729{
1730 assert(pDrawObject);
1731 if (m_pTextBoxes.empty())
1732 return;
1733
1734 for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end();)
1735 {
1736 if (it->m_pDrawObject == pDrawObject)
1737 {
1738 if (bDelFromDoc)
1739 {
1740 it->m_pTextBoxFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(
1741 it->m_pTextBoxFormat);
1742 // What about m_pTextBoxes? So, when the DelLayoutFormat() removes the format
1743 // then the ~SwFrameFormat() will call this method again to remove the entry.
1744 return;
1745 }
1746 else
1747 {
1748 it = m_pTextBoxes.erase(it);
1749 return;
1750 }
1751 }
1752 ++it;
1753 }
1754
1755 SAL_WARN("sw.core", "SwTextBoxNode::DelTextBox(): Not found!");
1756}
1757
1758void SwTextBoxNode::DelTextBox(const SwFrameFormat* pTextBox, bool bDelFromDoc)
1759{
1760 if (m_pTextBoxes.empty())
1761 return;
1762
1763 for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end();)
1764 {
1765 if (it->m_pTextBoxFormat == pTextBox)
1766 {
1767 if (bDelFromDoc)
1768 {
1769 it->m_pTextBoxFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(
1770 it->m_pTextBoxFormat);
1771 // What about m_pTextBoxes? So, when the DelLayoutFormat() removes the format
1772 // then the ~SwFrameFormat() will call this method again to remove the entry.
1773 return;
1774 }
1775 else
1776 {
1777 it = m_pTextBoxes.erase(it);
1778 return;
1779 }
1780 }
1781 ++it;
1782 }
1783
1784 SAL_WARN("sw.core", "SwTextBoxNode::DelTextBox(): Not found!");
1785}
1786
1788{
1789 assert(pDrawObject);
1790 assert(m_pOwnerShapeFormat);
1791
1792 if (auto& pTextBoxes = m_pOwnerShapeFormat->GetOtherTextBoxFormats())
1793 {
1794 if (size_t(pTextBoxes.use_count()) != pTextBoxes->GetTextBoxCount() + size_t(1))
1795 {
1796 SAL_WARN("sw.core", "SwTextBoxNode::GetTextBox(): RefCount and TexBox count mismatch!");
1797 }
1798 }
1799
1800 if (m_bLock)
1801 return nullptr;
1802
1803 if (!m_pTextBoxes.empty())
1804 {
1805 for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
1806 {
1807 if (it->m_pDrawObject == pDrawObject)
1808 {
1809 return it->m_pTextBoxFormat;
1810 }
1811 }
1812 SAL_WARN("sw.core", "SwTextBoxNode::GetTextBox(): Not found!");
1813 }
1814
1815 return nullptr;
1816}
1817
1819{
1820 // If this called from ~SwDoc(), then only the address entries
1821 // have to be removed, the format will be deleted by the
1822 // the mpSpzFrameFormatTable->DeleteAndDestroyAll() in ~SwDoc()!
1824 {
1825 m_pTextBoxes.clear();
1826 return;
1827 }
1828
1829 // For loop control
1830 sal_uInt16 nLoopCount = 0;
1831
1832 // Reference not enough, copy needed.
1833 const size_t nTextBoxCount = m_pTextBoxes.size();
1834
1835 // For loop has problems: When one entry deleted, the iterator has
1836 // to be refreshed according to the new situation. So using While() instead.
1837 while (!m_pTextBoxes.empty())
1838 {
1839 // Delete the last textbox of the vector from the doc
1840 // (what will call deregister in ~SwFrameFormat()
1842 m_pTextBoxes.back().m_pTextBoxFormat);
1843
1844 // Check if we are looping
1845 if (nLoopCount > (nTextBoxCount + 1))
1846 {
1847 SAL_WARN("sw.core", "SwTextBoxNode::ClearAll(): Maximum loop count reached!");
1848 break;
1849 }
1850 else
1851 {
1852 nLoopCount++;
1853 }
1854 }
1855
1856 // Ensure the vector is empty.
1857 if (!m_pTextBoxes.empty())
1858 {
1859 SAL_WARN("sw.core", "SwTextBoxNode::ClearAll(): Text-Box-Vector still not empty!");
1860 assert(false);
1861 }
1862}
1863
1864bool SwTextBoxNode::IsGroupTextBox() const { return m_pTextBoxes.size() > 1; }
1865
1866std::map<SdrObject*, SwFrameFormat*> SwTextBoxNode::GetAllTextBoxes() const
1867{
1868 std::map<SdrObject*, SwFrameFormat*> aRet;
1869 for (auto& rElem : m_pTextBoxes)
1870 {
1871 aRet.emplace(rElem.m_pDrawObject, rElem.m_pTextBoxFormat);
1872 }
1873 return aRet;
1874}
1875
1876void SwTextBoxNode::Clone(SwDoc* pDoc, const SwFormatAnchor& rNewAnc, SwFrameFormat* o_pTarget,
1877 bool bSetAttr, bool bMakeFrame) const
1878{
1879 if (!o_pTarget || !pDoc)
1880 return;
1881
1882 if (o_pTarget->Which() != RES_DRAWFRMFMT)
1883 return;
1884
1886 return;
1887
1889
1890 Clone_Impl(pDoc, rNewAnc, o_pTarget, m_pOwnerShapeFormat->FindSdrObject(),
1891 o_pTarget->FindSdrObject(), bSetAttr, bMakeFrame);
1892
1893 m_bIsCloningInProgress = false;
1894
1895 for (auto& rElem : m_pTextBoxes)
1896 {
1901 }
1902}
1903
1904void SwTextBoxNode::Clone_Impl(SwDoc* pDoc, const SwFormatAnchor& rNewAnc, SwFrameFormat* o_pTarget,
1905 const SdrObject* pSrcObj, SdrObject* pDestObj, bool bSetAttr,
1906 bool bMakeFrame) const
1907{
1908 if (!pSrcObj || !pDestObj)
1909 return;
1910
1911 auto pSrcList = pSrcObj->getChildrenOfSdrObject();
1912 auto pDestList = pDestObj->getChildrenOfSdrObject();
1913
1914 if (pSrcList && pDestList)
1915 {
1916 if (pSrcList->GetObjCount() != pDestList->GetObjCount())
1917 {
1918 SAL_WARN("sw.core", "SwTextBoxNode::Clone_Impl(): Difference between the shapes!");
1919 return;
1920 }
1921
1922 for (size_t i = 0; i < pSrcList->GetObjCount(); ++i)
1923 {
1924 Clone_Impl(pDoc, rNewAnc, o_pTarget, pSrcList->GetObj(i), pDestList->GetObj(i),
1925 bSetAttr, bMakeFrame);
1926 }
1927 return;
1928 }
1929
1930 if (!pSrcList && !pDestList)
1931 {
1932 if (auto pSrcFormat = GetTextBox(pSrcObj))
1933 {
1934 SwFormatAnchor aNewAnchor(rNewAnc);
1935 if (aNewAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
1936 {
1937 aNewAnchor.SetType(RndStdIds::FLY_AT_CHAR);
1938
1939 if (!bMakeFrame)
1940 bMakeFrame = true;
1941 }
1942
1943 if (auto pTargetFormat = pDoc->getIDocumentLayoutAccess().CopyLayoutFormat(
1944 *pSrcFormat, aNewAnchor, bSetAttr, bMakeFrame))
1945 {
1946 if (!o_pTarget->GetOtherTextBoxFormats())
1947 {
1948 auto pNewTextBoxes = std::make_shared<SwTextBoxNode>(SwTextBoxNode(o_pTarget));
1949 o_pTarget->SetOtherTextBoxFormats(pNewTextBoxes);
1950 pNewTextBoxes->AddTextBox(pDestObj, pTargetFormat);
1951 pTargetFormat->SetOtherTextBoxFormats(pNewTextBoxes);
1952 }
1953 else
1954 {
1955 o_pTarget->GetOtherTextBoxFormats()->AddTextBox(pDestObj, pTargetFormat);
1956 pTargetFormat->SetOtherTextBoxFormats(o_pTarget->GetOtherTextBoxFormats());
1957 }
1958 o_pTarget->SetFormatAttr(pTargetFormat->GetContent());
1959 }
1960 }
1961 }
1962}
1963
1964/* 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.
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long getX() const
constexpr tools::Long getY() const
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:197
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:408
bool IsInDtor() const
Definition: doc.hxx:417
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:158
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:419
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1337
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:169
const sw::FrameFormats< sw::SpzFrameFormat * > * GetSpzFrameFormats() const
Definition: doc.hxx:759
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
void SetTextBox(bool bIsTextBox)
Definition: dflyobj.hxx:56
FlyAnchors.
Definition: fmtanchr.hxx:37
sal_uInt16 GetPageNum() const
Definition: fmtanchr.hxx:70
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1593
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:1614
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:2187
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:98
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:72
void SetOtherTextBoxFormats(const std::shared_ptr< SwTextBoxNode > &rNew)
Definition: frmfmt.hxx:119
const std::shared_ptr< SwTextBoxNode > & GetOtherTextBoxFormats() const
Definition: frmfmt.hxx:118
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2802
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:153
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:275
const SwPosition * Start() const
Definition: pam.hxx:258
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 void saveLinks(const sw::FrameFormats< sw::SpzFrameFormat * > &rFormats, std::map< const SwFrameFormat *, const SwFrameFormat * > &rLinks)
Saves the current shape -> textbox links in a map, so they can be restored later.
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 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:516
static SW_DLLPUBLIC rtl::Reference< SwXTextFrame > CreateXTextFrame(SwDoc &rDoc, SwFrameFormat *pFrameFormat)
Definition: unoframe.cxx:3234
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:840
int nCount
#define DBG_TESTSOLARMUTEX()
float u
EmbeddedObjectRef * pObject
sal_Int16 nValue
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(126)
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(109)
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(108)
constexpr TypedWhichId< SvxOpaqueItem > RES_OPAQUE(105)
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(162)
constexpr TypedWhichId< SwFormatWrapInfluenceOnObjPos > RES_WRAP_INFLUENCE_ON_OBJPOS(132)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(165)
constexpr TypedWhichId< SwFormatAnchor > RES_ANCHOR(110)
constexpr TypedWhichId< SvxBoxItem > RES_BOX(112)
constexpr TypedWhichId< SdrTextVertAdjustItem > RES_TEXT_VERT_ADJUST(137)
constexpr TypedWhichId< SwFormatChain > RES_CHAIN(120)
constexpr TypedWhichId< SwFormatFollowTextFlow > RES_FOLLOW_TEXT_FLOW(130)
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(97)
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:1108
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_CHAIN_NEXT_NAME
Definition: unoprnms.hxx:255
constexpr OUStringLiteral UNO_NAME_FILL_TRANSPARENCE
constexpr OUStringLiteral UNO_NAME_TEXT_LOWERDIST
constexpr OUStringLiteral UNO_NAME_SIZE_TYPE
Definition: unoprnms.hxx:282
constexpr OUStringLiteral UNO_NAME_ALLOW_OVERLAP
Definition: unoprnms.hxx:914
constexpr OUStringLiteral UNO_NAME_SIZE
Definition: unoprnms.hxx:327
constexpr OUStringLiteral UNO_NAME_TEXT_VERT_ADJUST
Definition: unoprnms.hxx:903
constexpr OUStringLiteral UNO_NAME_TEXT_UPPERDIST
constexpr OUStringLiteral UNO_NAME_RIGHT_BORDER_DISTANCE
Definition: unoprnms.hxx:382
constexpr OUStringLiteral UNO_NAME_ANCHOR_TYPE
Definition: unoprnms.hxx:249
constexpr OUStringLiteral UNO_NAME_RIGHT_MARGIN
Definition: unoprnms.hxx:81
constexpr OUStringLiteral UNO_NAME_CHAIN_PREV_NAME
Definition: unoprnms.hxx:256
constexpr OUStringLiteral UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT
Definition: unoprnms.hxx:639
constexpr OUStringLiteral UNO_NAME_HORI_ORIENT_POSITION
Definition: unoprnms.hxx:288
constexpr OUStringLiteral UNO_NAME_BOTTOM_BORDER
Definition: unoprnms.hxx:379
constexpr OUStringLiteral UNO_NAME_VERT_ORIENT_POSITION
Definition: unoprnms.hxx:354
constexpr OUStringLiteral UNO_NAME_LEFT_MARGIN
Definition: unoprnms.hxx:80
constexpr OUStringLiteral UNO_NAME_HORI_ORIENT
Definition: unoprnms.hxx:284
constexpr OUStringLiteral UNO_NAME_BOTTOM_BORDER_DISTANCE
Definition: unoprnms.hxx:384
constexpr OUStringLiteral UNO_NAME_VERT_ORIENT
Definition: unoprnms.hxx:352
constexpr OUStringLiteral UNO_NAME_HORI_ORIENT_RELATION
Definition: unoprnms.hxx:287
constexpr OUStringLiteral UNO_NAME_TOP_BORDER
Definition: unoprnms.hxx:378
constexpr OUStringLiteral UNO_NAME_TEXT_HORZADJUST
constexpr OUStringLiteral UNO_NAME_RIGHT_BORDER
Definition: unoprnms.hxx:377
constexpr OUStringLiteral UNO_NAME_WRITING_MODE
Definition: unoprnms.hxx:726
constexpr OUStringLiteral UNO_NAME_TEXT_WORDWRAP
constexpr OUStringLiteral UNO_NAME_TEXT_VERTADJUST
constexpr OUStringLiteral UNO_NAME_TEXT_LEFTDIST
constexpr OUStringLiteral UNO_NAME_TEXT_WRITINGMODE
constexpr OUStringLiteral UNO_NAME_OPAQUE
Definition: unoprnms.hxx:306
constexpr OUStringLiteral UNO_NAME_TOP_BORDER_DISTANCE
Definition: unoprnms.hxx:383
constexpr OUStringLiteral UNO_NAME_TEXT_AUTOGROWHEIGHT
constexpr OUStringLiteral UNO_NAME_LEFT_BORDER_DISTANCE
Definition: unoprnms.hxx:381
constexpr OUStringLiteral UNO_NAME_SURROUND
Definition: unoprnms.hxx:333
constexpr OUStringLiteral UNO_NAME_VERT_ORIENT_RELATION
Definition: unoprnms.hxx:355
constexpr OUStringLiteral UNO_NAME_PARA_ADJUST
Definition: unoprnms.hxx:191
constexpr OUStringLiteral UNO_NAME_ANCHOR_PAGE_NO
Definition: unoprnms.hxx:251
constexpr OUStringLiteral UNO_NAME_RELATIVE_WIDTH_RELATION
Definition: unoprnms.hxx:212
constexpr OUStringLiteral UNO_NAME_LEFT_BORDER
Definition: unoprnms.hxx:376
constexpr OUStringLiteral UNO_NAME_TEXT_RIGHTDIST
constexpr OUStringLiteral UNO_NAME_RELATIVE_HEIGHT_RELATION
Definition: unoprnms.hxx:214
constexpr OUStringLiteral UNO_NAME_WIDTH_TYPE
Definition: unoprnms.hxx:777
constexpr OUStringLiteral UNO_NAME_IS_FOLLOWING_TEXT_FLOW
Definition: unoprnms.hxx:776