summaryrefslogtreecommitdiff
path: root/sw/source/core/doc
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2021-11-28 15:14:45 +0100
committerStephan Bergmann <sbergman@redhat.com>2021-11-28 18:03:04 +0100
commit2408a1ac6131d137704860f5f8b83bb98d62a4d1 (patch)
tree7ce9f355048b9272a8757adf316c72b2fae8c7db /sw/source/core/doc
parente2d63449aae4c3e4ffd6e405001ab56fbead5850 (diff)
Revert "tdf#129183 sw: textboxes in group shapes - part 3"
This reverts commit eabcfb3f18a6944d9ad89cecd3eb3ca7a2259cf3. Conflicts: sw/source/core/doc/textboxhelper.cxx It caused UITest_writer_tests4 to fail in an ASan build with > ==2987325==ERROR: AddressSanitizer: heap-use-after-free on address 0x6130000e5048 at pc 0x7f20cb3112ac bp 0x7f1e62de92d0 sp 0x7f1e62de92c8 > WRITE of size 8 at 0x6130000e5048 thread T47 > #0 in SwFrameFormat::SetOtherTextBoxFormat(SwTextBoxNode*) at sw/inc/frmfmt.hxx:106:77 > #1 in SwTextBoxNode::~SwTextBoxNode() at sw/source/core/doc/textboxhelper.cxx:1680:30 > #2 in SwFrameFormat::~SwFrameFormat() at sw/source/core/layout/atrfrm.cxx:2564:9 > #3 in SwDrawFrameFormat::~SwDrawFrameFormat() at sw/source/core/layout/atrfrm.cxx:3455:1 > #4 in SwDrawFrameFormat::~SwDrawFrameFormat() at sw/source/core/layout/atrfrm.cxx:3453:1 > #5 in SwFrameFormats::DeleteAndDestroyAll(bool) at sw/source/core/doc/docfmt.cxx:2115:9 > #6 in SwDoc::~SwDoc() at sw/source/core/doc/docnew.cxx:565:28 > #7 in SwDoc::release() at sw/source/core/doc/doc.cxx:118:9 > #8 in rtl::Reference<SwDoc>::clear() at include/rtl/ref.hxx:196:19 > #9 in SwDocShell::RemoveLink() at sw/source/uibase/app/docshini.cxx:444:16 > #10 in SwDocShell::~SwDocShell() at sw/source/uibase/app/docshini.cxx:372:5 > #11 in SwDocShell::~SwDocShell() at sw/source/uibase/app/docshini.cxx:362:1 > #12 in SwDocShell::~SwDocShell() at sw/source/uibase/app/docshini.cxx:362:1 > #13 in SvRefBase::ReleaseRef() at include/tools/ref.hxx:163:29 > #14 in tools::SvRef<SfxObjectShell>::~SvRef() at include/tools/ref.hxx:56:36 > #15 in IMPL_SfxBaseModel_DataContainer::~IMPL_SfxBaseModel_DataContainer() at sfx2/source/doc/sfxbasemodel.cxx:245:5 > #16 in void std::destroy_at<IMPL_SfxBaseModel_DataContainer>(IMPL_SfxBaseModel_DataContainer*) at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/stl_construct.h:88:15 > #17 in void std::allocator_traits<std::allocator<IMPL_SfxBaseModel_DataContainer> >::destroy<IMPL_SfxBaseModel_DataContainer>(std::allocator<IMPL_SfxBaseModel_DataContainer>&, IMPL_SfxBaseModel_DataContainer*) at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/alloc_traits.h:537:4 > #18 in std::_Sp_counted_ptr_inplace<IMPL_SfxBaseModel_DataContainer, std::allocator<IMPL_SfxBaseModel_DataContainer>, (__gnu_cxx::_Lock_policy)2>::_M_dispose() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:528:2 > #19 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:168:6 > #20 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:705:11 > #21 in std::__shared_ptr<IMPL_SfxBaseModel_DataContainer, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:1154:31 > #22 in std::__shared_ptr<IMPL_SfxBaseModel_DataContainer, (__gnu_cxx::_Lock_policy)2>::reset() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:1272:9 > #23 in SfxBaseModel::dispose() at sfx2/source/doc/sfxbasemodel.cxx:757:13 > #24 in SwXTextDocument::dispose() at sw/source/uibase/uno/unotxdoc.cxx:549:19 > #25 in SfxBaseModel::close(unsigned char) at sfx2/source/doc/sfxbasemodel.cxx:1482:5 > #26 in SwXTextDocument::close(unsigned char) at sw/source/uibase/uno/unotxdoc.cxx:562:19 > #27 in SfxBaseModel::dispose() at sfx2/source/doc/sfxbasemodel.cxx:718:13 > #28 in SwXTextDocument::dispose() at sw/source/uibase/uno/unotxdoc.cxx:549:19 > #29 in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) at bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:77:5 > #30 in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, _typelib_TypeDescriptionReference*, int, _typelib_MethodParameter*, void*, void**, _uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233:13 > #31 in unoInterfaceProxyDispatch at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:413:13 > #32 in binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny> >*) const at binaryurp/source/incomingrequest.cxx:235:13 > #33 in binaryurp::IncomingRequest::execute() const at binaryurp/source/incomingrequest.cxx:78:26 > #34 in request at binaryurp/source/reader.cxx:85:9 > #35 in cppu_threadpool::JobQueue::enter(void const*, bool) at cppu/source/threadpool/jobqueue.cxx:100:17 > #36 in cppu_threadpool::ORequestThread::run() at cppu/source/threadpool/thread.cxx:164:31 > #37 in threadFunc at include/osl/thread.hxx:189:15 > #38 in osl_thread_start_Impl(void*) at sal/osl/unx/thread.cxx:264:9 > #39 in start_thread at <null> > #40 in __GI___clone3 at <null> > > 0x6130000e5048 is located 328 bytes inside of 376-byte region [0x6130000e4f00,0x6130000e5078) > freed by thread T47 here: > #0 in operator delete(void*, unsigned long) at ~/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:164:3 > #1 in SwFlyFrameFormat::~SwFlyFrameFormat() at sw/source/core/layout/atrfrm.cxx:2912:1 > #2 in SwFrameFormats::DeleteAndDestroyAll(bool) at sw/source/core/doc/docfmt.cxx:2115:9 > #3 in SwDoc::~SwDoc() at sw/source/core/doc/docnew.cxx:565:28 > #4 in SwDoc::release() at sw/source/core/doc/doc.cxx:118:9 > #5 in rtl::Reference<SwDoc>::clear() at include/rtl/ref.hxx:196:19 > #6 in SwDocShell::RemoveLink() at sw/source/uibase/app/docshini.cxx:444:16 > #7 in SwDocShell::~SwDocShell() at sw/source/uibase/app/docshini.cxx:372:5 > #8 in SwDocShell::~SwDocShell() at sw/source/uibase/app/docshini.cxx:362:1 > #9 in SwDocShell::~SwDocShell() at sw/source/uibase/app/docshini.cxx:362:1 > #10 in SvRefBase::ReleaseRef() at include/tools/ref.hxx:163:29 > #11 in tools::SvRef<SfxObjectShell>::~SvRef() at include/tools/ref.hxx:56:36 > #12 in IMPL_SfxBaseModel_DataContainer::~IMPL_SfxBaseModel_DataContainer() at sfx2/source/doc/sfxbasemodel.cxx:245:5 > #13 in void std::destroy_at<IMPL_SfxBaseModel_DataContainer>(IMPL_SfxBaseModel_DataContainer*) at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/stl_construct.h:88:15 > #14 in void std::allocator_traits<std::allocator<IMPL_SfxBaseModel_DataContainer> >::destroy<IMPL_SfxBaseModel_DataContainer>(std::allocator<IMPL_SfxBaseModel_DataContainer>&, IMPL_SfxBaseModel_DataContainer*) at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/alloc_traits.h:537:4 > #15 in std::_Sp_counted_ptr_inplace<IMPL_SfxBaseModel_DataContainer, std::allocator<IMPL_SfxBaseModel_DataContainer>, (__gnu_cxx::_Lock_policy)2>::_M_dispose() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:528:2 > #16 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:168:6 > #17 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:705:11 > #18 in std::__shared_ptr<IMPL_SfxBaseModel_DataContainer, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:1154:31 > #19 in std::__shared_ptr<IMPL_SfxBaseModel_DataContainer, (__gnu_cxx::_Lock_policy)2>::reset() at ~/gcc/trunk/inst/lib/gcc/x86_64-pc-linux-gnu/12.0.0/../../../../include/c++/12.0.0/bits/shared_ptr_base.h:1272:9 > > previously allocated by thread T10 here: > #0 in operator new(unsigned long) at ~/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:95:3 > #1 in SwDoc::MakeFlyFrameFormat(rtl::OUString const&, SwFrameFormat*) at sw/source/core/doc/docfmt.cxx:756:33 > #2 in SwDoc::MakeFlySection_(SwPosition const&, SwContentNode const&, RndStdIds, SfxItemSet const*, SwFrameFormat*) at sw/source/core/doc/doclay.cxx:171:33 > #3 in SwDoc::MakeFlySection(RndStdIds, SwPosition const*, SfxItemSet const*, SwFrameFormat*, bool) at sw/source/core/doc/doclay.cxx:337:19 > #4 in SwXFrame::attachToRange(com::sun::star::uno::Reference<com::sun::star::text::XTextRange> const&, SwPaM const*) at sw/source/core/unocore/unoframe.cxx:2821:29 > #5 in SwXFrame::attach(com::sun::star::uno::Reference<com::sun::star::text::XTextRange> const&) at sw/source/core/unocore/unoframe.cxx:3115:9 > #6 in SwXTextFrame::attach(com::sun::star::uno::Reference<com::sun::star::text::XTextRange> const&) at sw/source/core/unocore/unoframe.cxx:3346:15 > #7 in SwXText::insertTextContent(com::sun::star::uno::Reference<com::sun::star::text::XTextRange> const&, com::sun::star::uno::Reference<com::sun::star::text::XTextContent> const&, unsigned char) at sw/source/core/unocore/unotext.cxx:615:15 > #8 in SwXText::insertTextContentWithProperties(com::sun::star::uno::Reference<com::sun::star::text::XTextContent> const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::text::XTextRange> const&) at sw/source/core/unocore/unotext.cxx:1472:5 > #9 in non-virtual thunk to SwXText::insertTextContentWithProperties(com::sun::star::uno::Reference<com::sun::star::text::XTextContent> const&, com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue> const&, com::sun::star::uno::Reference<com::sun::star::text::XTextRange> const&) at sw/source/core/unocore/unotext.cxx > #10 in SwTextBoxHelper::create(SwFrameFormat*, SdrObject*, bool) at sw/source/core/doc/textboxhelper.cxx:100:29 > #11 in SwXShape::setPropertyValue(rtl::OUString const&, com::sun::star::uno::Any const&) at sw/source/core/unocore/unodraw.cxx:1165:25 > #12 in SdXMLShapeContext::SetStyle(bool) at xmloff/source/draw/ximpshap.cxx:701:27 > #13 in SdXMLCustomShapeContext::startFastElement(int, com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> const&) at xmloff/source/draw/ximpshap.cxx:3545:5 > #14 in SvXMLImport::startFastElement(int, com::sun::star::uno::Reference<com::sun::star::xml::sax::XFastAttributeList> const&) at xmloff/source/core/xmlimp.cxx:805:15 > #15 in (anonymous namespace)::Entity::startElement((anonymous namespace)::Event const*) at sax/source/fastparser/fastparser.cxx:468:27 > #16 in sax_fastparser::FastSaxParserImpl::callbackStartElement(unsigned char const*, unsigned char const*, unsigned char const*, int, unsigned char const**, int, unsigned char const**) at sax/source/fastparser/fastparser.cxx:1304:21 > #17 in (anonymous namespace)::call_callbackStartElement(void*, unsigned char const*, unsigned char const*, unsigned char const*, int, unsigned char const**, int, int, unsigned char const**) at sax/source/fastparser/fastparser.cxx:331:18 > #18 in xmlParseStartTag2 at workdir/UnpackedTarball/libxml2/parser.c:9658:6 > #19 in xmlParseTryOrFinish at workdir/UnpackedTarball/libxml2/parser.c:11453:14 Change-Id: I752190e05fc3c282b75021724527f623f56ee6a6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125977 Tested-by: Jenkins Tested-by: René Engelhard <rene@debian.org> Reviewed-by: Stephan Bergmann <sbergman@redhat.com> (cherry picked from commit 4fb7967fb2e67717f79eb87519c1444a82350a83) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125906
Diffstat (limited to 'sw/source/core/doc')
-rw-r--r--sw/source/core/doc/DocumentLayoutManager.cxx45
-rw-r--r--sw/source/core/doc/docdraw.cxx55
-rw-r--r--sw/source/core/doc/docfly.cxx11
-rw-r--r--sw/source/core/doc/textboxhelper.cxx492
4 files changed, 140 insertions, 463 deletions
diff --git a/sw/source/core/doc/DocumentLayoutManager.cxx b/sw/source/core/doc/DocumentLayoutManager.cxx
index ae49a77183c0..c67e9e05e9a6 100644
--- a/sw/source/core/doc/DocumentLayoutManager.cxx
+++ b/sw/source/core/doc/DocumentLayoutManager.cxx
@@ -312,39 +312,7 @@ void DocumentLayoutManager::DelLayoutFormat( SwFrameFormat *pFormat )
}
m_rDoc.getIDocumentState().SetModified();
}
-#if 0
-// TODO: Replace the textbox part of frameformat copying method to this.
-// Now disabled because cause asserts in sw (Node index is still registered in dtor).
-// Without this nested group textboxes are not handled correctly.
-static void lcl_CopyTextBoxes(SwDoc* pDoc, SwTextBoxNode* pSrcTextBoxes, const SdrObject* pSrcObj,
- SwTextBoxNode* pDestTextBoxes, SdrObject* pDestObj,
- bool bSetTextFlyAtt, bool bMakeFrames)
-{
- auto pSrcChildren = pSrcObj->getChildrenOfSdrObject();
- auto pDestChildren = pDestObj->getChildrenOfSdrObject();
- if (pSrcChildren && pDestChildren)
- {
- if (pSrcChildren->GetObjCount() == pDestChildren->GetObjCount())
- for (size_t i = 0; i < pSrcChildren->GetObjCount(); ++i)
- {
- lcl_CopyTextBoxes(pDoc, pSrcTextBoxes, pSrcChildren->GetObj(i), pDestTextBoxes,
- pDestChildren->GetObj(i), bSetTextFlyAtt, bMakeFrames);
- }
- }
- else
- {
- if (auto pSourceTextBoxFormat = pSrcTextBoxes->GetTextBox(pSrcObj))
- {
- assert(pSourceTextBoxFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR);
- auto pNewTextBoxFormat = pDoc->GetDocumentLayoutManager().CopyLayoutFormat(
- *pSourceTextBoxFormat, pSourceTextBoxFormat->GetAnchor(), bSetTextFlyAtt,
- bMakeFrames);
- pDestTextBoxes->AddTextBox(pDestObj, pNewTextBoxFormat);
- pNewTextBoxFormat->SetOtherTextBoxFormat(pDestTextBoxes);
- }
- }
-}
-#endif
+
/** Copies the stated format (pSrc) to pDest and returns pDest.
If there's no pDest, it is created.
@@ -501,18 +469,7 @@ SwFrameFormat *DocumentLayoutManager::CopyLayoutFormat(
auto pObj = rSource.FindRealSdrObject();
auto pTextBoxNd = new SwTextBoxNode(pDest);
pDest->SetOtherTextBoxFormat(pTextBoxNd);
-#if 0
- // TODO: Change the copy algorithm to this. See comment in lcl_CopyTextBoxes for details.
- if (!bMakeFrames && rNewAnchor.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
- {
- // If the draw format is as-char, then it will be copied with bMakeFrames=false, but
- // doing the same for the fly format would result in not making fly frames at all.
- bMakeFrames = true;
- }
- lcl_CopyTextBoxes(&m_rDoc, rSource.GetOtherTextBoxFormat(), rSource.FindRealSdrObject(),
- pTextBoxNd, pDest->FindRealSdrObject(), bSetTextFlyAtt, bMakeFrames);
-#endif
if (pObj)
{
const bool bIsGroupObj = pObj->getChildrenOfSdrObject();
diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx
index 39adffb8b5a0..0aff4b8993ff 100644
--- a/sw/source/core/doc/docdraw.cxx
+++ b/sw/source/core/doc/docdraw.cxx
@@ -209,7 +209,7 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
bGroupMembersNotPositioned = pAnchoredDrawObj->NotYetPositioned();
}
- std::unordered_map<const SdrObject*, SwFrameFormat*> vSavedTextBoxes;
+ std::vector<std::pair<SwFrameFormat*, SdrObject*>> vSavedTextBoxes;
// Destroy ContactObjects and formats.
for( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
{
@@ -224,13 +224,8 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
"<SwDoc::GroupSelection(..)> - group members have different positioning status!" );
#endif
// Before the format will be killed, save its textbox for later use.
- if (auto pTxBxNd = pContact->GetFormat()->GetOtherTextBoxFormat())
- {
- for (auto& rElem : pTxBxNd->GetTextBoxTable())
- {
- vSavedTextBoxes.emplace(rElem);
- }
- }
+ if (auto pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pContact->GetFormat(), RES_DRAWFRMFMT, pObj))
+ vSavedTextBoxes.push_back(std::pair<SwFrameFormat*, SdrObject*>(pTextBox, pObj));
pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
// Deletes itself!
@@ -261,8 +256,8 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
auto pTextBoxNode = new SwTextBoxNode(pFormat);
for (auto& pTextBoxEntry : vSavedTextBoxes)
{
- pTextBoxNode->AddTextBox(const_cast<SdrObject*>(pTextBoxEntry.first), pTextBoxEntry.second);
- pTextBoxEntry.second->SetOtherTextBoxFormat(pTextBoxNode);
+ pTextBoxNode->AddTextBox(pTextBoxEntry.second, pTextBoxEntry.first);
+ pTextBoxEntry.first->SetOtherTextBoxFormat(pTextBoxNode);
}
pFormat->SetOtherTextBoxFormat(pTextBoxNode);
vSavedTextBoxes.clear();
@@ -304,27 +299,6 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
return pNewContact;
}
-static void lcl_CollectTextBoxesForSubGroupObj(SwFrameFormat* pTargetFormat, SwTextBoxNode* pTextBoxNode,
- SdrObject* pSourceObjs)
-{
- if (auto pChildrenObjs = pSourceObjs->getChildrenOfSdrObject())
- for (size_t i = 0; i < pChildrenObjs->GetObjCount(); ++i)
- lcl_CollectTextBoxesForSubGroupObj(pTargetFormat, pTextBoxNode, pChildrenObjs->GetObj(i));
- else
- {
- if (auto pTextBox = pTextBoxNode->GetTextBox(pSourceObjs))
- {
- if (!pTargetFormat->GetOtherTextBoxFormat())
- {
- pTargetFormat->SetOtherTextBoxFormat(new SwTextBoxNode(pTargetFormat));
- }
-
- pTargetFormat->GetOtherTextBoxFormat()->AddTextBox(pSourceObjs, pTextBox);
- pTextBox->SetOtherTextBoxFormat(pTargetFormat->GetOtherTextBoxFormat());
- }
- }
-}
-
void SwDoc::UnGroupSelection( SdrView& rDrawView )
{
bool const bUndo = GetIDocumentUndoRedo().DoesUndo();
@@ -375,22 +349,13 @@ void SwDoc::UnGroupSelection( SdrView& rDrawView )
pFormat->SetFormatAttr( aAnch );
if (pTextBoxNode)
- {
- if (!pSubObj->getChildrenOfSdrObject())
- {
- if (auto pTextBoxFormat = pTextBoxNode->GetTextBox(pSubObj))
- {
- auto pNewTextBoxNode = new SwTextBoxNode(pFormat);
- pNewTextBoxNode->AddTextBox(pSubObj, pTextBoxFormat);
- pFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
- pTextBoxFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
- };
- }
- else
+ if (auto pTextBoxFormat = pTextBoxNode->GetTextBox(pSubObj))
{
- lcl_CollectTextBoxesForSubGroupObj(pFormat, pTextBoxNode, pSubObj);
+ auto pNewTextBoxNode = new SwTextBoxNode(pFormat);
+ pNewTextBoxNode->AddTextBox(pSubObj, pTextBoxFormat);
+ pFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
+ pTextBoxFormat->SetOtherTextBoxFormat(pNewTextBoxNode);
}
- }
// #i36010# - set layout direction of the position
pFormat->SetPositionLayoutDir(
diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx
index 16365ebbbfec..6b73f1f756b5 100644
--- a/sw/source/core/doc/docfly.cxx
+++ b/sw/source/core/doc/docfly.cxx
@@ -577,6 +577,8 @@ bool SwDoc::SetFlyFrameAttr( SwFrameFormat& rFlyFormat, SfxItemSet& rSet )
getIDocumentState().SetModified();
+ //SwTextBoxHelper::syncFlyFrameAttr(rFlyFormat, rSet);
+
return bRet;
}
@@ -918,9 +920,12 @@ bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList,
pNd->InsertItem( aFormat, aPos.nContent.GetIndex(), 0 );
// Has a textbox attached to the format? Sync it as well!
- SwTextBoxHelper::syncFlyFrameAttr(*pContact->GetFormat(),
- pContact->GetFormat()->GetAttrSet(), pObj);
-
+ if (SwTextBoxHelper::getOtherTextBoxFormat(pContact->GetFormat(),
+ RES_DRAWFRMFMT))
+ {
+ SwTextBoxHelper::syncFlyFrameAttr(*pContact->GetFormat(),
+ pContact->GetFormat()->GetAttrSet(), pObj);
+ }
}
break;
default:
diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index 3fc5c4a56313..418c69927228 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -187,8 +187,7 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape, SdrObject* pObject, bool bCo
syncProperty(pShape, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)), pObject);
if (bIsGroupObj)
- handleTextBoxGroup(
- pShape, SwTextBoxHelper::GroupTextBoxActionType::POSITION_SIZE_AND_ANCHOR_CHANGE);
+ doTextBoxPositioning(pShape, pObject);
// Check if the shape had text before and move it to the new textframe
if (!bCopyText || sCopyableText.isEmpty())
@@ -208,156 +207,18 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape, SdrObject* pObject, bool bCo
}
}
-void SwTextBoxHelper::set(SwFrameFormat* pShapeFormat, SdrObject* pObj,
- uno::Reference<text::XTextFrame> xNew)
-{
- // Do not set invalid data
- assert(pShapeFormat && pObj && xNew);
- // Firstly find the format of the new textbox.
- SwFrameFormat* pFormat = nullptr;
- if (auto pTextFrame = dynamic_cast<SwXTextFrame*>(xNew.get()))
- pFormat = pTextFrame->GetFrameFormat();
- if (!pFormat)
- return;
- std::vector<std::pair<beans::Property, uno::Any>> aOldProps;
- // If there is a format, check if the shape already has a textbox assigned to.
- if (auto pTextBoxNode = pShapeFormat->GetOtherTextBoxFormat())
- {
- // If it has a texbox, destroy it.
- if (pTextBoxNode->GetTextBox(pObj))
- {
- auto xOldFrame
- = pObj->getUnoShape()->queryInterface(cppu::UnoType<text::XTextRange>::get());
- if (xOldFrame.hasValue())
- {
- uno::Reference<beans::XPropertySet> xOldprops(xOldFrame, uno::UNO_QUERY);
- uno::Reference<beans::XPropertyState> xOldPropStates(xOldFrame, uno::UNO_QUERY);
- for (auto& rProp : xOldprops->getPropertySetInfo()->getProperties())
- {
- try
- {
- if (xOldPropStates->getPropertyState(rProp.Name)
- == beans::PropertyState::PropertyState_DIRECT_VALUE)
- aOldProps.push_back(
- std::pair(rProp, xOldprops->getPropertyValue(rProp.Name)));
- }
- catch (...)
- {
- }
- }
- }
- destroy(pShapeFormat, pObj);
- }
- // And set the new one.
- pTextBoxNode->AddTextBox(pObj, pFormat);
- pFormat->SetOtherTextBoxFormat(pTextBoxNode);
- }
- else
- {
- // If the shape do not have a texbox node and textbox,
- // create that for the shape.
- auto* pTextBox = new SwTextBoxNode(pShapeFormat);
- pTextBox->AddTextBox(pObj, pFormat);
- pShapeFormat->SetOtherTextBoxFormat(pTextBox);
- pFormat->SetOtherTextBoxFormat(pTextBox);
- }
-
- // Initialize its properties
- uno::Reference<beans::XPropertySet> xPropertySet(xNew, uno::UNO_QUERY);
- uno::Any aEmptyBorder = uno::makeAny(table::BorderLine2());
- xPropertySet->setPropertyValue(UNO_NAME_TOP_BORDER, aEmptyBorder);
- xPropertySet->setPropertyValue(UNO_NAME_BOTTOM_BORDER, aEmptyBorder);
- xPropertySet->setPropertyValue(UNO_NAME_LEFT_BORDER, aEmptyBorder);
- xPropertySet->setPropertyValue(UNO_NAME_RIGHT_BORDER, aEmptyBorder);
- xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::makeAny(sal_Int32(100)));
- xPropertySet->setPropertyValue(UNO_NAME_SIZE_TYPE, uno::makeAny(text::SizeType::FIX));
- xPropertySet->setPropertyValue(UNO_NAME_SURROUND, uno::makeAny(text::WrapTextMode_THROUGH));
- // Add a new name to it
- uno::Reference<container::XNamed> xNamed(xNew, uno::UNO_QUERY);
- xNamed->setName(pShapeFormat->GetDoc()->GetUniqueFrameName());
- // And sync. properties.
- uno::Reference<drawing::XShape> xShape(pObj->getUnoShape(), uno::UNO_QUERY);
- syncProperty(pShapeFormat, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::makeAny(xShape->getSize()),
- pObj);
-
- uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
- syncProperty(pShapeFormat, RES_ANCHOR, MID_ANCHOR_ANCHORTYPE,
- xShapePropertySet->getPropertyValue(UNO_NAME_ANCHOR_TYPE), pObj);
- syncProperty(pShapeFormat, RES_HORI_ORIENT, MID_HORIORIENT_ORIENT,
- xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT), pObj);
- syncProperty(pShapeFormat, RES_HORI_ORIENT, MID_HORIORIENT_RELATION,
- xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_RELATION), pObj);
- syncProperty(pShapeFormat, RES_VERT_ORIENT, MID_VERTORIENT_ORIENT,
- xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT), pObj);
- syncProperty(pShapeFormat, RES_VERT_ORIENT, MID_VERTORIENT_RELATION,
- xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_RELATION), pObj);
- syncProperty(pShapeFormat, RES_HORI_ORIENT, MID_HORIORIENT_POSITION,
- xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_POSITION), pObj);
- syncProperty(pShapeFormat, RES_VERT_ORIENT, MID_VERTORIENT_POSITION,
- xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_POSITION), pObj);
- syncProperty(pShapeFormat, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT,
- xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT), pObj);
-
- drawing::TextVerticalAdjust aVertAdj = drawing::TextVerticalAdjust_CENTER;
-
- if ((uno::Reference<beans::XPropertyState>(xShape, uno::UNO_QUERY_THROW))
- ->getPropertyState(UNO_NAME_TEXT_VERT_ADJUST)
- != beans::PropertyState::PropertyState_DEFAULT_VALUE)
- {
- aVertAdj = xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_VERT_ADJUST)
- .get<drawing::TextVerticalAdjust>();
- }
-
- xPropertySet->setPropertyValue(UNO_NAME_TEXT_VERT_ADJUST, uno::makeAny(aVertAdj));
- text::WritingMode eMode;
- if (xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_WRITINGMODE) >>= eMode)
- syncProperty(pShapeFormat, RES_FRAMEDIR, 0, uno::makeAny(sal_Int16(eMode)), pObj);
- if (aOldProps.size())
- {
- for (auto& rProp : aOldProps)
- {
- try
- {
- xPropertySet->setPropertyValue(rProp.first.Name, rProp.second);
- }
- catch (...)
- {
- }
- }
- }
- if (pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
- && pFormat->GetAnchor().GetPageNum() == 0)
- {
- pFormat->SetFormatAttr(SwFormatAnchor(RndStdIds::FLY_AT_PAGE, 1));
- }
- // Do sync for the new textframe.
- handleTextBoxGroup(pShapeFormat, GroupTextBoxActionType::POSITION_SIZE_AND_ANCHOR_CHANGE);
-}
-
void SwTextBoxHelper::destroy(const SwFrameFormat* pShape, const SdrObject* pObject)
{
- assert(pShape && pObject);
-
// If a TextBox was enabled previously
- auto pTextBoxNode = pShape->GetOtherTextBoxFormat();
- if (!pTextBoxNode)
- {
- SAL_WARN("sw.core", "SwTextBoxHelper::destroy: No TextBoxNode!");
- return;
- }
-
- if (auto pFormat = pTextBoxNode->GetTextBox(pObject))
+ auto pTextBox = pShape->GetOtherTextBoxFormat();
+ if (pTextBox && pTextBox->IsTextBoxActive(pObject))
{
// Unlink the TextBox's text range from the original shape.
- pTextBoxNode->DelTextBox(pObject);
- pFormat->SetOtherTextBoxFormat(nullptr);
+ pTextBox->SetTextBoxInactive(pObject);
// Delete the associated TextFrame.
- pFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(pFormat);
- return;
+ pTextBox->DelTextBox(pObject);
}
-
- SAL_WARN("sw.core", "SwTextBoxHelper::destroy: No TextBox to destroy!");
}
bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pFormat, sal_uInt16 nType,
@@ -372,9 +233,6 @@ bool SwTextBoxHelper::isTextBox(const SwFrameFormat* pFormat, sal_uInt16 nType,
if (!pTextBox)
return false;
- if (!pTextBox->GetTextBoxCount())
- return false;
-
if (nType == RES_DRAWFRMFMT)
{
if (pObject)
@@ -475,12 +333,6 @@ sal_Int32 SwTextBoxHelper::getOrdNum(const SdrObject* pObject)
void SwTextBoxHelper::getShapeWrapThrough(const SwFrameFormat* pTextBox, bool& rWrapThrough)
{
- if (!pTextBox->GetOtherTextBoxFormat())
- {
- SAL_WARN("sw.core", "SwTextBoxHelper::getShapeWrapThrough: No TextBoxNode!");
- return;
- }
-
SwFrameFormat* pShape = SwTextBoxHelper::getOtherTextBoxFormat(pTextBox, RES_FLYFRMFMT);
if (pShape)
rWrapThrough = pShape->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH;
@@ -515,8 +367,7 @@ SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XS
return nullptr;
SwFrameFormat* pFormat = pShape->GetFrameFormat();
- return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT,
- SdrObject::getSdrObjectFromXShape(xShape));
+ return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT);
}
uno::Reference<text::XTextFrame>
@@ -537,49 +388,33 @@ SwTextBoxHelper::getUnoTextFrame(uno::Reference<drawing::XShape> const& xShape)
return {};
}
-uno::Any SwTextBoxHelper::queryInterface(const SwFrameFormat* pShape, const uno::Type& rType,
- SdrObject* pObj)
+template <typename T> static void lcl_queryInterface(const SwFrameFormat* pShape, uno::Any& rAny)
{
- if (!pShape)
- return {};
-
- if (!pShape->GetOtherTextBoxFormat())
+ if (SwFrameFormat* pFormat = SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
{
- SAL_WARN("sw.core", "SwTextBoxHelper::queryInterface: No TextBoxNode!");
- return {};
- }
-
- SwFrameFormat* pFormat = SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj);
-
- if (!pFormat)
- {
- SAL_WARN("sw.core", "SwTextBoxHelper::queryInterface: No TextBox!");
- return {};
+ uno::Reference<T> const xInterface(
+ SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
+ rAny <<= xInterface;
}
+}
+uno::Any SwTextBoxHelper::queryInterface(const SwFrameFormat* pShape, const uno::Type& rType)
+{
uno::Any aRet;
if (rType == cppu::UnoType<css::text::XTextAppend>::get())
{
- uno::Reference<css::text::XTextAppend> const xInterface(
- SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY_THROW);
- aRet <<= xInterface;
+ lcl_queryInterface<text::XTextAppend>(pShape, aRet);
}
else if (rType == cppu::UnoType<css::text::XText>::get())
{
- uno::Reference<css::text::XText> const xInterface(
- SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY_THROW);
- aRet <<= xInterface;
+ lcl_queryInterface<text::XText>(pShape, aRet);
}
else if (rType == cppu::UnoType<css::text::XTextRange>::get())
{
- uno::Reference<css::text::XTextRange> const xInterface(
- SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY_THROW);
- aRet <<= xInterface;
+ lcl_queryInterface<text::XTextRange>(pShape, aRet);
}
- assert(aRet.hasValue());
-
return aRet;
}
@@ -1073,51 +908,6 @@ void SwTextBoxHelper::restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrame
}
}
-void SwTextBoxHelper::handleTextBoxGroup(SwFrameFormat* pGroupShapeFormat,
- GroupTextBoxActionType eActionType,
- SdrObject* pGroupObject)
-{
- if (!pGroupShapeFormat)
- return;
-
- SdrObject* pMasterObj = nullptr;
- if (!pGroupObject)
- pMasterObj = pGroupShapeFormat->FindRealSdrObject();
- else
- pMasterObj = pGroupObject;
-
- if (auto pChildrenObjs = pMasterObj->getChildrenOfSdrObject())
- {
- for (size_t i = 0; i < pChildrenObjs->GetObjCount(); ++i)
- handleTextBoxGroup(pGroupShapeFormat, eActionType, pChildrenObjs->GetObj(i));
- }
- else
- {
- switch (eActionType)
- {
- case GroupTextBoxActionType::POSITION_SIZE_AND_ANCHOR_CHANGE:
- {
- changeAnchor(pGroupShapeFormat, pMasterObj);
- setTextBoxSize(pGroupShapeFormat, pMasterObj);
- break;
- }
- case GroupTextBoxActionType::Z_ORDER_CHANGE:
- {
- DoTextBoxZOrderCorrection(pGroupShapeFormat, pMasterObj);
- break;
- }
- case GroupTextBoxActionType::DELETE:
- {
- destroy(pGroupShapeFormat, pMasterObj);
- break;
- }
- default:
- SAL_WARN("sw.core", "SwTextBoxHelper::handleTextBoxGroup: Unknown Action!");
- break;
- }
- }
-}
-
text::TextContentAnchorType SwTextBoxHelper::mapAnchorType(const RndStdIds& rAnchorID)
{
text::TextContentAnchorType aAnchorType;
@@ -1276,6 +1066,7 @@ void SwTextBoxHelper::syncFlyFrameAttr(SwFrameFormat& rShape, SfxItemSet const&
if (aTextBoxSet.Count())
pFormat->SetFormatAttr(aTextBoxSet);
+ //pFormat->GetDoc()->SetFlyFrameAttr(*pFormat, aTextBoxSet);
DoTextBoxZOrderCorrection(&rShape, pObj);
}
@@ -1323,11 +1114,12 @@ void SwTextBoxHelper::updateTextBoxMargin(SdrObject* pObj)
DoTextBoxZOrderCorrection(pParentFormat, pObj);
}
-bool SwTextBoxHelper::setWrapThrough(SwFrameFormat* pShape, SdrObject* pObj)
+bool SwTextBoxHelper::setWrapThrough(SwFrameFormat* pShape)
{
- if (isTextBoxShapeHasValidTextFrame(pShape, pObj))
+ OUString sErrMsg;
+ if (isTextBoxShapeHasValidTextFrame(pShape))
{
- if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
+ if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
{
::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
if (auto xFrame = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat))
@@ -1340,77 +1132,53 @@ bool SwTextBoxHelper::setWrapThrough(SwFrameFormat* pShape, SdrObject* pObj)
}
catch (uno::Exception& e)
{
- SAL_WARN("sw.core",
- "SwTextBoxHelper::setWrapThrough: Exception caught: " << e.Message);
+ sErrMsg = "Exception caught: " + e.Message;
}
else
- SAL_WARN("sw.core", "SwTextBoxHelper::setWrapThrough: No XTextFrame!");
+ sErrMsg = "No XTextFrame!";
}
else
- SAL_WARN("sw.core", "SwTextBoxHelper::setWrapThrough: No Other TextBox Format!");
+ sErrMsg = "No Other TextBox Format!";
}
else
- SAL_WARN("sw.core", "SwTextBoxHelper::setWrapThrough: Not a Valid TextBox object!");
+ sErrMsg = "Not a Valid TextBox object!";
+ SAL_WARN("sw.core", "SwTextBoxHelper::setWrapThrough: " << sErrMsg);
return false;
}
bool SwTextBoxHelper::changeAnchor(SwFrameFormat* pShape, SdrObject* pObj)
{
- // Get the desired textbox from the shape
if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
{
- // Collect the anchors
const SwFormatAnchor& rOldAnch = pFormat->GetAnchor();
const SwFormatAnchor& rNewAnch = pShape->GetAnchor();
- // Collect the anchor positions (in the text)
const auto pOldCnt = rOldAnch.GetContentAnchor();
const auto pNewCnt = rNewAnch.GetContentAnchor();
- // Collect the relative anchor points
const uno::Any aShapeHorRelOrient
= uno::makeAny(pShape->GetHoriOrient().GetRelationOrient());
- const uno::Any aShapeVertRelOrient
- = uno::makeAny(pShape->GetVertOrient().GetRelationOrient());
- // Get the new page number. If this is 0 increase it to 1!
- // (0 is invalid page)
- const sal_uInt16 nPageNum = rNewAnch.GetPageNum() ? rNewAnch.GetPageNum() : 1;
-
- // If anchor is different, sync needed
- if (isAnchorTypeDifferent(pShape, pObj) || (pObj && pObj != pShape->FindRealSdrObject()))
+ if (isAnchorTypeDifferent(pShape) || (pObj && pObj != pShape->FindRealSdrObject()))
{
try
{
- // Disable undo for the sync
::sw::UndoGuard const UndoGuard(pShape->GetDoc()->GetIDocumentUndoRedo());
- // Get the properties of the textframe
uno::Reference<beans::XPropertySet> const xPropertySet(
SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY);
-
- // Anchoring situations:
-
- // First:
- // the old anchor is in the text (namely inline or at_char/para) and,
- // the new one will be at_page
if (pOldCnt && rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
&& rNewAnch.GetPageNum())
{
uno::Any aValue(text::TextContentAnchorType_AT_PAGE);
xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
aShapeHorRelOrient);
- xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
- aShapeVertRelOrient);
xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
- xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO, uno::Any(nPageNum));
+ xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO,
+ uno::Any(rNewAnch.GetPageNum()));
}
- // Second:
- // The reverse of the previous one: Old one at page, new at-text.
else if (rOldAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE && pNewCnt)
{
- // If the new at-text anchor is inline, the textbox can not be inline too,
- // so change it to at_char and make its position according to the shape.
if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
{
uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
@@ -1423,28 +1191,17 @@ bool SwTextBoxHelper::changeAnchor(SwFrameFormat* pShape, SdrObject* pObj)
aPos.SetAnchor(pNewCnt);
pFormat->SetFormatAttr(aPos);
}
- // Else, copy the anchor of the shape to the frame. Correct pagenum if needed.
else
{
uno::Any aValue(mapAnchorType(rNewAnch.GetAnchorId()));
xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
aShapeHorRelOrient);
- xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
- aShapeVertRelOrient);
xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_TYPE, aValue);
- if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
- && !rNewAnch.GetPageNum())
- xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO,
- uno::Any(sal_uInt16(1)));
-
pFormat->SetFormatAttr(rNewAnch);
}
}
- // Third:
- // At-text anchor changes to at-text. (Only the type changes)
else
{
- // Special treatment for inline case.
if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)
{
uno::Any aValue(text::TextContentAnchorType_AT_CHARACTER);
@@ -1457,19 +1214,10 @@ bool SwTextBoxHelper::changeAnchor(SwFrameFormat* pShape, SdrObject* pObj)
aPos.SetAnchor(pNewCnt);
pFormat->SetFormatAttr(aPos);
}
- // Else, just copy the anchor.
else
{
xPropertySet->setPropertyValue(UNO_NAME_HORI_ORIENT_RELATION,
aShapeHorRelOrient);
- xPropertySet->setPropertyValue(UNO_NAME_VERT_ORIENT_RELATION,
- aShapeVertRelOrient);
-
- if (rNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE
- && !rNewAnch.GetPageNum())
- xPropertySet->setPropertyValue(UNO_NAME_ANCHOR_PAGE_NO,
- uno::Any(sal_uInt16(1)));
-
pFormat->SetFormatAttr(pShape->GetAnchor());
}
}
@@ -1505,12 +1253,6 @@ bool SwTextBoxHelper::doTextBoxPositioning(SwFrameFormat* pShape, SdrObject* pOb
SwFormatVertOrient aNewVOri(pFormat->GetVertOrient());
aNewVOri.SetPos(aRect.Top() + pShape->GetVertOrient().GetPos());
- if (bIsGroupObj)
- {
- aNewHOri.SetPos(aNewHOri.GetPos() + pObj->GetRelativePos().getX());
- aNewVOri.SetPos(aNewVOri.GetPos() + pObj->GetRelativePos().getY());
- }
-
// tdf#140598: Do not apply wrong rectangle position.
if (aRect.TopLeft() != Point(0, 0))
{
@@ -1530,11 +1272,11 @@ bool SwTextBoxHelper::doTextBoxPositioning(SwFrameFormat* pShape, SdrObject* pOb
{
SwFormatHoriOrient aNewHOri(pShape->GetHoriOrient());
aNewHOri.SetPos(
- ((bIsGroupObj && pObj) ? pObj->GetRelativePos().getX() : aNewHOri.GetPos())
+ (bIsGroupObj && pObj ? pObj->GetRelativePos().getX() : aNewHOri.GetPos())
+ aRect.Left());
SwFormatVertOrient aNewVOri(pShape->GetVertOrient());
aNewVOri.SetPos(
- ((bIsGroupObj && pObj) ? pObj->GetRelativePos().getY() : aNewVOri.GetPos())
+ (bIsGroupObj && pObj ? pObj->GetRelativePos().getY() : aNewVOri.GetPos())
+ aRect.Top());
pFormat->SetFormatAttr(aNewHOri);
@@ -1549,31 +1291,12 @@ bool SwTextBoxHelper::doTextBoxPositioning(SwFrameFormat* pShape, SdrObject* pOb
return false;
}
-bool SwTextBoxHelper::setTextBoxSize(const SwFrameFormat* pShape, SdrObject* pObj)
-{
- if (!pShape || !pObj)
- return false;
-
- if (auto pTBox = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
- {
- const auto& rSize = getTextRectangle(pObj, false).GetSize();
- if (!rSize.IsEmpty())
- {
- SwFormatFrameSize aSizeFormatItem = pTBox->GetFrameSize();
- aSizeFormatItem.SetSize(rSize);
- return pTBox->SetFormatAttr(aSizeFormatItem);
- }
- }
- return false;
-}
-
-std::optional<bool> SwTextBoxHelper::isAnchorTypeDifferent(const SwFrameFormat* pShape,
- SdrObject* pObj)
+std::optional<bool> SwTextBoxHelper::isAnchorTypeDifferent(const SwFrameFormat* pShape)
{
std::optional<bool> bRet;
- if (isTextBoxShapeHasValidTextFrame(pShape, pObj))
+ if (isTextBoxShapeHasValidTextFrame(pShape))
{
- if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
+ if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
{
if (pShape->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR)
bRet = (pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AT_CHAR
@@ -1585,21 +1308,20 @@ std::optional<bool> SwTextBoxHelper::isAnchorTypeDifferent(const SwFrameFormat*
return bRet;
}
-bool SwTextBoxHelper::isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShape, SdrObject* pObj)
+bool SwTextBoxHelper::isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShape)
{
if (pShape && pShape->Which() == RES_DRAWFRMFMT)
- if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj))
+ if (auto pFormat = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT))
if (pFormat && pFormat->Which() == RES_FLYFRMFMT)
return true;
else
- SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: Shape does "
- "not have valid textframe!");
+ SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: "
+ "Shape does not have valid textframe!");
else
- SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: Shape does not "
- "have associated frame!");
+ SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: "
+ "Shape does not have associated frame!");
else
- SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: No valid shape");
-
+ SAL_WARN("sw.core", "SwTextBoxHelper::isTextBoxShapeHasValidTextFrame: Not valid shape!");
return false;
}
@@ -1607,6 +1329,9 @@ bool SwTextBoxHelper::DoTextBoxZOrderCorrection(SwFrameFormat* pShape, const Sdr
{
// TODO: do this with group shape textboxes.
SdrObject* pShpObj = nullptr;
+ //if (pObj)
+ // pShpObj = pObj;
+ //else
pShpObj = pShape->FindRealSdrObject();
if (pShpObj)
@@ -1640,53 +1365,39 @@ bool SwTextBoxHelper::DoTextBoxZOrderCorrection(SwFrameFormat* pShape, const Sdr
break;
++nIterator;
if (nIterator > 300)
- {
break; // Do not run to infinity
- }
}
pPage->RecalcObjOrdNums();
return true; // Success
}
- SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): No Valid Draw model "
- "for SdrObject for the shape!");
+ SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
+ "No Valid Draw model for SdrObject for the shape!");
}
- SAL_WARN("sw.core",
- "SwTextBoxHelper::DoTextBoxZOrderCorrection(): No Valid SdrObject for the frame!");
+ SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
+ "No Valid SdrObject for the frame!");
}
- SAL_WARN("sw.core",
- "SwTextBoxHelper::DoTextBoxZOrderCorrection(): No Valid SdrObject for the shape!");
+ SAL_WARN("sw.core", "SwTextBoxHelper::DoTextBoxZOrderCorrection(): "
+ "No Valid SdrObject for the shape!");
return false;
}
-// SwTextBoxNode class:
-
SwTextBoxNode::SwTextBoxNode(SwFrameFormat* pOwnerShape)
{
assert(pOwnerShape);
assert(pOwnerShape->Which() == RES_DRAWFRMFMT);
m_pOwnerShapeFormat = pOwnerShape;
- if (!m_pTextBoxTable.empty())
- m_pTextBoxTable.clear();
+ if (!m_pTextBoxes.empty())
+ m_pTextBoxes.clear();
}
SwTextBoxNode::~SwTextBoxNode()
{
- if (m_pTextBoxTable.size())
- {
- for (auto& rTextBox : m_pTextBoxTable)
- {
- rTextBox.second->SetOtherTextBoxFormat(nullptr);
- rTextBox.second = nullptr;
- }
- m_pTextBoxTable.clear();
- }
+ m_pTextBoxes.clear();
if (m_pOwnerShapeFormat && m_pOwnerShapeFormat->GetOtherTextBoxFormat())
m_pOwnerShapeFormat->SetOtherTextBoxFormat(nullptr);
-
- m_pOwnerShapeFormat = nullptr;
}
void SwTextBoxNode::AddTextBox(SdrObject* pDrawObject, SwFrameFormat* pNewTextBox)
@@ -1696,63 +1407,102 @@ void SwTextBoxNode::AddTextBox(SdrObject* pDrawObject, SwFrameFormat* pNewTextBo
assert(pDrawObject);
- if (!m_pTextBoxTable.count(pDrawObject))
- {
- m_pTextBoxTable.emplace(pDrawObject, pNewTextBox);
- }
- else
- {
- m_pTextBoxTable[pDrawObject] = pNewTextBox;
- }
+ SwTextBoxElement aElem;
+ aElem.m_bIsActive = true;
+ aElem.m_pDrawObject = pDrawObject;
+ aElem.m_pTextBoxFormat = pNewTextBox;
auto pSwFlyDraw = dynamic_cast<SwFlyDrawObj*>(pDrawObject);
if (pSwFlyDraw)
{
pSwFlyDraw->SetTextBox(true);
}
+ m_pTextBoxes.push_back(aElem);
}
void SwTextBoxNode::DelTextBox(const SdrObject* pDrawObject)
{
assert(pDrawObject);
- auto pObj = const_cast<SdrObject*>(pDrawObject);
-
- if (m_pTextBoxTable.empty())
+ if (m_pTextBoxes.empty())
return;
- if (m_pTextBoxTable.count(pObj))
+ for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end();)
{
- m_pTextBoxTable[pObj]->SetOtherTextBoxFormat(nullptr);
- m_pTextBoxTable.erase(pObj);
+ if (it->m_pDrawObject == pDrawObject)
+ {
+ m_pOwnerShapeFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat(
+ it->m_pTextBoxFormat);
+ it = m_pTextBoxes.erase(it);
+ break;
+ }
+ ++it;
}
}
-void SwTextBoxNode::DelTextBox(SwFrameFormat* pTextBox)
+SwFrameFormat* SwTextBoxNode::GetTextBox(const SdrObject* pDrawObject) const
{
- if (!pTextBox || m_pTextBoxTable.empty())
- return;
+ assert(pDrawObject);
+ if (!m_pTextBoxes.empty())
+ {
+ for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
+ {
+ if (it->m_pDrawObject == pDrawObject)
+ {
+ return it->m_pTextBoxFormat;
+ }
+ }
+ }
+ return nullptr;
+}
- for (auto it = m_pTextBoxTable.begin(); it != m_pTextBoxTable.end(); ++it)
- if (it->second == pTextBox)
+bool SwTextBoxNode::IsTextBoxActive(const SdrObject* pDrawObject) const
+{
+ assert(pDrawObject);
+
+ if (!m_pTextBoxes.empty())
+ {
+ for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
{
- it->second->SetOtherTextBoxFormat(nullptr);
- m_pTextBoxTable.erase(it->first);
- break;
+ if (it->m_pDrawObject == pDrawObject)
+ {
+ return it->m_bIsActive;
+ }
}
+ }
+ return false;
}
-SwFrameFormat* SwTextBoxNode::GetTextBox(const SdrObject* pDrawObject) const
+void SwTextBoxNode::SetTextBoxActive(const SdrObject* pDrawObject)
{
assert(pDrawObject);
- if (!m_pTextBoxTable.empty())
+
+ if (!m_pTextBoxes.empty())
{
- if (m_pTextBoxTable.count(pDrawObject))
+ for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
{
- return m_pTextBoxTable.at(pDrawObject);
+ if (it->m_pDrawObject == pDrawObject)
+ {
+ it->m_bIsActive = true;
+ }
+ }
+ }
+}
+
+void SwTextBoxNode::SetTextBoxInactive(const SdrObject* pDrawObject)
+{
+ assert(pDrawObject);
+
+ if (!m_pTextBoxes.empty())
+ {
+ for (auto it = m_pTextBoxes.begin(); it != m_pTextBoxes.end(); it++)
+ {
+ if (it->m_pDrawObject == pDrawObject)
+ {
+ it->m_bIsActive = false;
+ }
}
}
- return nullptr;
}
-bool SwTextBoxNode::IsGroupTextBoxShape() const { return m_pTextBoxTable.size() > 1; }
+bool SwTextBoxNode::IsGroupTextBox() const { return m_pTextBoxes.size() > 1; }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */