LCOV - code coverage report
Current view: top level - sw/source/core/doc - textboxhelper.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 316 335 94.3 %
Date: 2014-11-03 Functions: 24 24 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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>
      17             : #include <IDocumentLayoutAccess.hxx>
      18             : #include <ndtxt.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 <unoprnms.hxx>
      26             : #include <dflyobj.hxx>
      27             : #include <mvsave.hxx>
      28             : #include <sortedobjs.hxx>
      29             : #include <anchoredobject.hxx>
      30             : #include <cntfrm.hxx>
      31             : 
      32             : #include <editeng/unoprnms.hxx>
      33             : #include <editeng/charrotateitem.hxx>
      34             : #include <svx/svdoashp.hxx>
      35             : #include <svx/svdpage.hxx>
      36             : #include <svl/itemiter.hxx>
      37             : #include <comphelper/sequenceashashmap.hxx>
      38             : 
      39             : #include <com/sun/star/document/XActionLockable.hpp>
      40             : #include <com/sun/star/table/BorderLine2.hpp>
      41             : #include <com/sun/star/text/SizeType.hpp>
      42             : #include <com/sun/star/text/TextContentAnchorType.hpp>
      43             : #include <com/sun/star/text/WrapTextMode.hpp>
      44             : #include <com/sun/star/text/XTextDocument.hpp>
      45             : 
      46             : using namespace com::sun::star;
      47             : 
      48         824 : void SwTextBoxHelper::create(SwFrmFmt* pShape)
      49             : {
      50             :     // If TextBox wasn't enabled previously
      51         824 :     if (!pShape->GetAttrSet().HasItem(RES_CNTNT))
      52             :     {
      53             :         // Create the associated TextFrame and insert it into the document.
      54         824 :         uno::Reference<text::XTextContent> xTextFrame(SwXServiceProvider::MakeInstance(SW_SERVICE_TYPE_TEXTFRAME, *pShape->GetDoc()), uno::UNO_QUERY);
      55        1648 :         uno::Reference<text::XTextDocument> xTextDocument(pShape->GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
      56        1648 :         uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(), uno::UNO_QUERY);
      57         824 :         xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>());
      58             : 
      59             :         // Initialize properties.
      60        1648 :         uno::Reference<beans::XPropertySet> xPropertySet(xTextFrame, uno::UNO_QUERY);
      61        1648 :         uno::Any aEmptyBorder = uno::makeAny(table::BorderLine2());
      62         824 :         xPropertySet->setPropertyValue(UNO_NAME_TOP_BORDER, aEmptyBorder);
      63         824 :         xPropertySet->setPropertyValue(UNO_NAME_BOTTOM_BORDER, aEmptyBorder);
      64         824 :         xPropertySet->setPropertyValue(UNO_NAME_LEFT_BORDER, aEmptyBorder);
      65         824 :         xPropertySet->setPropertyValue(UNO_NAME_RIGHT_BORDER, aEmptyBorder);
      66             : 
      67         824 :         xPropertySet->setPropertyValue(UNO_NAME_FILL_TRANSPARENCE, uno::makeAny(sal_Int32(100)));
      68             : 
      69         824 :         xPropertySet->setPropertyValue(UNO_NAME_SIZE_TYPE, uno::makeAny(text::SizeType::FIX));
      70             : 
      71        1648 :         uno::Reference<container::XNamed> xNamed(xTextFrame, uno::UNO_QUERY);
      72         824 :         xNamed->setName(pShape->GetDoc()->GetUniqueFrameName());
      73             : 
      74             :         // Link its text range to the original shape.
      75        1648 :         uno::Reference<text::XTextRange> xTextBox(xTextFrame, uno::UNO_QUERY_THROW);
      76        1648 :         SwUnoInternalPaM aInternalPaM(*pShape->GetDoc());
      77         824 :         if (sw::XTextRangeToSwPaM(aInternalPaM, xTextBox))
      78             :         {
      79         824 :             SwAttrSet aSet(pShape->GetAttrSet());
      80        1648 :             SwFmtCntnt aCntnt(aInternalPaM.GetNode().StartOfSectionNode());
      81         824 :             aSet.Put(aCntnt);
      82        1648 :             pShape->SetFmtAttr(aSet);
      83             :         }
      84             : 
      85             :         // Also initialize the properties, which are not constant, but inherited from the shape's ones.
      86        1648 :         uno::Reference<drawing::XShape> xShape(pShape->FindRealSdrObject()->getUnoShape(), uno::UNO_QUERY);
      87         824 :         syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::makeAny(xShape->getSize()));
      88             : 
      89        1648 :         uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY);
      90         824 :         syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_ORIENT, xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT));
      91         824 :         syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_RELATION, xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_RELATION));
      92         824 :         syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_ORIENT, xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT));
      93         824 :         syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_RELATION, xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_RELATION));
      94         824 :         syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_POSITION, xShapePropertySet->getPropertyValue(UNO_NAME_HORI_ORIENT_POSITION));
      95         824 :         syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_POSITION, xShapePropertySet->getPropertyValue(UNO_NAME_VERT_ORIENT_POSITION));
      96         824 :         syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT));
      97        1648 :         syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0, xShapePropertySet->getPropertyValue(UNO_NAME_TEXT_VERT_ADJUST));
      98             :     }
      99         824 : }
     100             : 
     101         260 : void SwTextBoxHelper::destroy(SwFrmFmt* pShape)
     102             : {
     103             :     // If a TextBox was enabled previously
     104         260 :     if (pShape->GetAttrSet().HasItem(RES_CNTNT))
     105             :     {
     106           0 :         SwFrmFmt* pFmt = findTextBox(pShape);
     107             : 
     108             :         // Unlink the TextBox's text range from the original shape.
     109           0 :         pShape->ResetFmtAttr(RES_CNTNT);
     110             : 
     111             :         // Delete the associated TextFrame.
     112           0 :         if (pFmt)
     113           0 :             pShape->GetDoc()->getIDocumentLayoutAccess().DelLayoutFmt(pFmt);
     114             :     }
     115         260 : }
     116             : 
     117        4604 : std::set<const SwFrmFmt*> SwTextBoxHelper::findTextBoxes(const SwDoc* pDoc)
     118             : {
     119        4604 :     std::set<const SwFrmFmt*> aRet;
     120             : 
     121        4604 :     const SwFrmFmts& rSpzFrmFmts = *pDoc->GetSpzFrmFmts();
     122       16106 :     for (SwFrmFmts::const_iterator it = rSpzFrmFmts.begin(); it != rSpzFrmFmts.end(); ++it)
     123             :     {
     124       11502 :         SwFrmFmt* pTextBox = findTextBox(*it);
     125       11502 :         if (pTextBox)
     126        1050 :             aRet.insert(pTextBox);
     127             :     }
     128             : 
     129        4604 :     return aRet;
     130             : }
     131             : 
     132        1584 : std::set<const SwFrmFmt*> SwTextBoxHelper::findTextBoxes(const SwNode& rNode)
     133             : {
     134        1584 :     const SwDoc* pDoc = rNode.GetDoc();
     135        1584 :     const SwCntntNode* pCntntNode = 0;
     136        1584 :     const SwCntntFrm* pCntntFrm = 0;
     137        1584 :     bool bHaveViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
     138        1584 :     if (bHaveViewShell && (pCntntNode = rNode.GetCntntNode()) && (pCntntFrm = pCntntNode->getLayoutFrm(pDoc->getIDocumentLayoutAccess().GetCurrentLayout())))
     139             :     {
     140             :         // We can use the layout information to iterate over only the frames which are anchored to us.
     141        1576 :         std::set<const SwFrmFmt*> aRet;
     142        1576 :         const SwSortedObjs* pSortedObjs = pCntntFrm->GetDrawObjs();
     143        1576 :         if (pSortedObjs)
     144             :         {
     145        1144 :             for (size_t i = 0; i < pSortedObjs->size(); ++i)
     146             :             {
     147         824 :                 SwAnchoredObject* pAnchoredObject = (*pSortedObjs)[i];
     148         824 :                 SwFrmFmt* pTextBox = findTextBox(&pAnchoredObject->GetFrmFmt());
     149         824 :                 if (pTextBox)
     150           4 :                     aRet.insert(pTextBox);
     151             :             }
     152             :         }
     153        1576 :         return aRet;
     154             :     }
     155             :     else
     156             :         // If necessary, here we could manually limit the returned set to the
     157             :         // ones which are anchored to rNode, but currently no need to do so.
     158           8 :         return findTextBoxes(pDoc);
     159             : }
     160             : 
     161        3427 : std::map<SwFrmFmt*, SwFrmFmt*> SwTextBoxHelper::findShapes(const SwDoc* pDoc)
     162             : {
     163        3427 :     std::map<SwFrmFmt*, SwFrmFmt*> aRet;
     164             : 
     165        3427 :     const SwFrmFmts& rSpzFrmFmts = *pDoc->GetSpzFrmFmts();
     166       26215 :     for (SwFrmFmts::const_iterator it = rSpzFrmFmts.begin(); it != rSpzFrmFmts.end(); ++it)
     167             :     {
     168       22788 :         SwFrmFmt* pTextBox = findTextBox(*it);
     169       22788 :         if (pTextBox)
     170        4168 :             aRet[pTextBox] = *it;
     171             :     }
     172             : 
     173        3427 :     return aRet;
     174             : }
     175             : 
     176             : /// If the passed SdrObject is in fact a TextFrame, that is used as a TextBox.
     177        1710 : bool lcl_isTextBox(SdrObject* pSdrObject, std::set<const SwFrmFmt*>& rTextBoxes)
     178             : {
     179        1710 :     SwVirtFlyDrawObj* pObject = PTR_CAST(SwVirtFlyDrawObj, pSdrObject);
     180        1710 :     return pObject && rTextBoxes.find(pObject->GetFmt()) != rTextBoxes.end();
     181             : }
     182             : 
     183         238 : sal_Int32 SwTextBoxHelper::getCount(SdrPage* pPage, std::set<const SwFrmFmt*>& rTextBoxes)
     184             : {
     185         238 :     sal_Int32 nRet = 0;
     186        1538 :     for (size_t i = 0; i < pPage->GetObjCount(); ++i)
     187             :     {
     188        1300 :         if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes))
     189         590 :             continue;
     190         710 :         ++nRet;
     191             :     }
     192         238 :     return nRet;
     193             : }
     194             : 
     195         170 : uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, sal_Int32 nIndex, std::set<const SwFrmFmt*>& rTextBoxes) throw(lang::IndexOutOfBoundsException)
     196             : {
     197         170 :     if (nIndex < 0 || nIndex >= getCount(pPage, rTextBoxes))
     198           0 :         throw lang::IndexOutOfBoundsException();
     199             : 
     200         170 :     SdrObject* pRet = 0;
     201         170 :     sal_Int32 nCount = 0; // Current logical index.
     202         410 :     for (size_t i = 0; i < pPage->GetObjCount(); ++i)
     203             :     {
     204         410 :         if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes))
     205          60 :             continue;
     206         350 :         if (nCount == nIndex)
     207             :         {
     208         170 :             pRet = pPage->GetObj(i);
     209         170 :             break;
     210             :         }
     211         180 :         ++nCount;
     212             :     }
     213             :     assert(pRet);
     214         170 :     return pRet ? uno::makeAny(uno::Reference<drawing::XShape>(pRet->getUnoShape(), uno::UNO_QUERY)) : uno::Any();
     215             : }
     216             : 
     217         348 : SwFrmFmt* SwTextBoxHelper::findTextBox(uno::Reference<drawing::XShape> xShape)
     218             : {
     219         348 :     SwXShape* pShape = dynamic_cast<SwXShape*>(xShape.get());
     220         348 :     if (!pShape)
     221           0 :         return 0;
     222             : 
     223         348 :     return findTextBox(pShape->GetFrmFmt());
     224             : }
     225             : 
     226      163125 : SwFrmFmt* SwTextBoxHelper::findTextBox(const SwFrmFmt* pShape)
     227             : {
     228      163125 :     SwFrmFmt* pRet = 0;
     229             : 
     230             :     // Only draw frames can have TextBoxes.
     231      163125 :     if (pShape->Which() == RES_DRAWFRMFMT && pShape->GetAttrSet().HasItem(RES_CNTNT))
     232             :     {
     233       45026 :         const SwFmtCntnt& rCntnt = pShape->GetCntnt();
     234       45026 :         const SwFrmFmts& rSpzFrmFmts = *pShape->GetDoc()->GetSpzFrmFmts();
     235     1457256 :         for (SwFrmFmts::const_iterator it = rSpzFrmFmts.begin(); it != rSpzFrmFmts.end(); ++it)
     236             :         {
     237     1457256 :             SwFrmFmt* pFmt = *it;
     238             :             // Only a fly frame can be a TextBox.
     239     1457256 :             if (pFmt->Which() == RES_FLYFRMFMT && pFmt->GetAttrSet().HasItem(RES_CNTNT) && pFmt->GetCntnt() == rCntnt)
     240             :             {
     241       45026 :                 pRet = pFmt;
     242       45026 :                 break;
     243             :             }
     244             :         }
     245             :     }
     246             : 
     247      163125 :     return pRet;
     248             : }
     249             : 
     250             : template < typename T >
     251        9364 : void lcl_queryInterface(SwFrmFmt* pShape, uno::Any& rAny)
     252             : {
     253        9364 :     if (SwFrmFmt* pFmt = SwTextBoxHelper::findTextBox(pShape))
     254             :     {
     255             :         uno::Reference<T> const xInterface(
     256        2818 :             SwXTextFrame::CreateXTextFrame(*pFmt->GetDoc(), pFmt),
     257        2818 :             uno::UNO_QUERY);
     258        2818 :         rAny <<= xInterface;
     259             :     }
     260        9364 : }
     261             : 
     262      840967 : uno::Any SwTextBoxHelper::queryInterface(SwFrmFmt* pShape, const uno::Type& rType)
     263             : {
     264      840967 :     uno::Any aRet;
     265             : 
     266      840967 :     if (rType == cppu::UnoType<css::text::XTextAppend>::get())
     267             :     {
     268        2834 :         lcl_queryInterface<text::XTextAppend>(pShape, aRet);
     269             :     }
     270      838133 :     else if (rType == cppu::UnoType<css::text::XText>::get())
     271             :     {
     272        4240 :         lcl_queryInterface<text::XText>(pShape, aRet);
     273             :     }
     274      833893 :     else if (rType == cppu::UnoType<css::text::XTextRange>::get())
     275             :     {
     276        2290 :         lcl_queryInterface<text::XTextRange>(pShape, aRet);
     277             :     }
     278             : 
     279             : 
     280      840967 :     return aRet;
     281             : }
     282             : 
     283        7942 : Rectangle SwTextBoxHelper::getTextRectangle(SwFrmFmt* pShape, bool bAbsolute)
     284             : {
     285        7942 :     Rectangle aRet;
     286        7942 :     aRet.SetEmpty();
     287        7942 :     SdrObjCustomShape* pCustomShape = dynamic_cast<SdrObjCustomShape*>(pShape->FindRealSdrObject());
     288        7942 :     if (pCustomShape)
     289             :     {
     290             :         // Need to temporarily release the lock acquired in
     291             :         // SdXMLShapeContext::AddShape(), otherwise we get an empty rectangle,
     292             :         // see EnhancedCustomShapeEngine::getTextBounds().
     293        7942 :         uno::Reference<document::XActionLockable> xLockable(pCustomShape->getUnoShape(), uno::UNO_QUERY);
     294        7942 :         sal_Int16 nLocks = 0;
     295        7942 :         if (xLockable.is())
     296        7942 :             nLocks = xLockable->resetActionLocks();
     297        7942 :         pCustomShape->GetTextBounds(aRet);
     298        7942 :         if (nLocks)
     299        5534 :             xLockable->setActionLocks(nLocks);
     300             :     }
     301             : 
     302        7942 :     if (!bAbsolute && pCustomShape)
     303             :     {
     304             :         // Relative, so count the logic (reference) rectangle, see the EnhancedCustomShape2d ctor.
     305        7870 :         Point aPoint(pCustomShape->GetSnapRect().Center());
     306        7870 :         Size aSize(pCustomShape->GetLogicRect().GetSize());
     307        7870 :         aPoint.X() -= aSize.Width() / 2;
     308        7870 :         aPoint.Y() -= aSize.Height() / 2;
     309        7870 :         Rectangle aLogicRect(aPoint, aSize);
     310        7870 :         aRet.Move(-1 * aLogicRect.Left(), -1 * aLogicRect.Top());
     311             :     }
     312             : 
     313        7942 :     return aRet;
     314             : }
     315             : 
     316      107248 : void SwTextBoxHelper::syncProperty(SwFrmFmt* pShape, const OUString& rPropertyName, const css::uno::Any& rValue)
     317             : {
     318      107248 :     if (rPropertyName == "CustomShapeGeometry")
     319             :     {
     320             :         // CustomShapeGeometry changes the textbox position offset and size, so adjust both.
     321        3744 :         syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_SIZE, uno::Any());
     322             : 
     323        3696 :         SdrObject* pObject = pShape->FindRealSdrObject();
     324        3696 :         if (pObject)
     325             :         {
     326        3696 :             Rectangle aRectangle(pObject->GetSnapRect());
     327        3696 :             syncProperty(pShape, RES_HORI_ORIENT, MID_HORIORIENT_POSITION, uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Left()))));
     328        3696 :             syncProperty(pShape, RES_VERT_ORIENT, MID_VERTORIENT_POSITION, uno::makeAny(static_cast<sal_Int32>(convertTwipToMm100(aRectangle.Top()))));
     329             :         }
     330             : 
     331        3696 :         if (SwFrmFmt* pFmt = findTextBox(pShape))
     332             :         {
     333        1204 :             comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue);
     334             :             // That would be the btLr text direction which we don't support at a frame level, so do it at a character level.
     335        1204 :             if (aCustomShapeGeometry.find("TextPreRotateAngle") != aCustomShapeGeometry.end() && aCustomShapeGeometry["TextPreRotateAngle"].get<sal_Int32>() == -270)
     336             :             {
     337          22 :                 if (const SwNodeIndex* pNodeIndex = pFmt->GetCntnt().GetCntntIdx())
     338             :                 {
     339          22 :                     SwPaM aPaM(*pFmt->GetDoc()->GetNodes()[pNodeIndex->GetIndex() + 1], 0);
     340          22 :                     aPaM.SetMark();
     341          22 :                     if (SwTxtNode* pMark = pFmt->GetDoc()->GetNodes()[pNodeIndex->GetNode().EndOfSectionIndex() - 1]->GetTxtNode())
     342             :                     {
     343          22 :                         aPaM.GetMark()->nNode = *pMark;
     344          22 :                         aPaM.GetMark()->nContent.Assign(pMark, pMark->GetTxt().getLength());
     345          22 :                         SvxCharRotateItem aItem(900, false, RES_CHRATR_ROTATE);
     346          22 :                         pFmt->GetDoc()->getIDocumentContentOperations().InsertPoolItem(aPaM, aItem, 0);
     347          22 :                     }
     348             :                 }
     349        1204 :             }
     350             :         }
     351             :     }
     352      103528 :     else if (rPropertyName == UNO_NAME_TEXT_VERT_ADJUST)
     353        5728 :         syncProperty(pShape, RES_TEXT_VERT_ADJUST, 0, rValue);
     354       97800 :     else if (rPropertyName == UNO_NAME_TEXT_AUTOGROWHEIGHT)
     355        7716 :         syncProperty(pShape, RES_FRM_SIZE, MID_FRMSIZE_IS_AUTO_HEIGHT, rValue);
     356      107224 : }
     357             : 
     358          18 : void SwTextBoxHelper::getProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 nMemberId, css::uno::Any& rValue)
     359             : {
     360          18 :     if (!pShape)
     361          18 :         return;
     362             : 
     363          18 :     nMemberId &= ~CONVERT_TWIPS;
     364             : 
     365          18 :     if (SwFrmFmt* pFmt = findTextBox(pShape))
     366             :     {
     367          18 :         if (nWID == RES_CHAIN)
     368             :         {
     369          18 :             switch (nMemberId)
     370             :             {
     371             :             case MID_CHAIN_PREVNAME:
     372             :             case MID_CHAIN_NEXTNAME:
     373             :             {
     374           0 :                 const SwFmtChain& rChain = pFmt->GetChain();
     375           0 :                 rChain.QueryValue(rValue, nMemberId);
     376             :             }
     377           0 :             break;
     378             :             case MID_CHAIN_NAME:
     379          18 :                 rValue = uno::makeAny(pFmt->GetName());
     380          18 :                 break;
     381             :             }
     382             :         }
     383             :     }
     384             : }
     385             : 
     386       84134 : void SwTextBoxHelper::syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 nMemberId, const css::uno::Any& rValue)
     387             : {
     388             :     // No shape yet? Then nothing to do, initial properties are set by create().
     389       84134 :     if (!pShape)
     390        1196 :         return;
     391             : 
     392       83938 :     uno::Any aValue(rValue);
     393       83938 :     nMemberId &= ~CONVERT_TWIPS;
     394             : 
     395       83938 :     if (SwFrmFmt* pFmt = findTextBox(pShape))
     396             :     {
     397       30022 :         OUString aPropertyName;
     398       30022 :         bool bAdjustX = false;
     399       30022 :         bool bAdjustY = false;
     400       30022 :         bool bAdjustSize = false;
     401       30022 :         switch (nWID)
     402             :         {
     403             :         case RES_HORI_ORIENT:
     404        6078 :             switch (nMemberId)
     405             :             {
     406             :             case MID_HORIORIENT_ORIENT:
     407        1618 :                 aPropertyName = UNO_NAME_HORI_ORIENT;
     408        1618 :                 break;
     409             :             case MID_HORIORIENT_RELATION:
     410        1618 :                 aPropertyName = UNO_NAME_HORI_ORIENT_RELATION;
     411        1618 :                 break;
     412             :             case MID_HORIORIENT_POSITION:
     413        2048 :                 aPropertyName = UNO_NAME_HORI_ORIENT_POSITION;
     414        2048 :                 bAdjustX = true;
     415        2048 :                 break;
     416             :             }
     417        6078 :             break;
     418             :         case RES_VERT_ORIENT:
     419        5284 :             switch (nMemberId)
     420             :             {
     421             :             case MID_VERTORIENT_ORIENT:
     422        1618 :                 aPropertyName = UNO_NAME_VERT_ORIENT;
     423        1618 :                 break;
     424             :             case MID_VERTORIENT_RELATION:
     425        1618 :                 aPropertyName = UNO_NAME_VERT_ORIENT_RELATION;
     426        1618 :                 break;
     427             :             case MID_VERTORIENT_POSITION:
     428        2048 :                 aPropertyName = UNO_NAME_VERT_ORIENT_POSITION;
     429        2048 :                 bAdjustY = true;
     430        2048 :                 break;
     431             :             }
     432        5284 :             break;
     433             :         case RES_FRM_SIZE:
     434        5252 :             switch (nMemberId)
     435             :             {
     436             :             case MID_FRMSIZE_IS_AUTO_HEIGHT:
     437        1490 :                 aPropertyName = UNO_NAME_FRAME_ISAUTOMATIC_HEIGHT;
     438        1490 :                 break;
     439             :             default:
     440        3762 :                 aPropertyName = UNO_NAME_SIZE;
     441        3762 :                 bAdjustSize = true;
     442        3762 :                 break;
     443             :             }
     444        5252 :             break;
     445             :         case RES_ANCHOR:
     446        1598 :             switch (nMemberId)
     447             :             {
     448             :             case MID_ANCHOR_ANCHORTYPE:
     449        1598 :                 if (aValue.get<text::TextContentAnchorType>() == text::TextContentAnchorType_AS_CHARACTER)
     450             :                 {
     451             :                     uno::Reference<beans::XPropertySet> const xPropertySet(
     452         804 :                         SwXTextFrame::CreateXTextFrame(*pFmt->GetDoc(), pFmt),
     453         804 :                         uno::UNO_QUERY);
     454         804 :                     xPropertySet->setPropertyValue(UNO_NAME_SURROUND, uno::makeAny(text::WrapTextMode_THROUGHT));
     455         804 :                     return;
     456             :                 }
     457         794 :                 break;
     458             :             }
     459         794 :             break;
     460             :         case FN_TEXT_RANGE:
     461             :         {
     462        1608 :             uno::Reference<text::XTextRange> xRange;
     463        1608 :             rValue >>= xRange;
     464        3216 :             SwUnoInternalPaM aInternalPaM(*pFmt->GetDoc());
     465        1608 :             if (sw::XTextRangeToSwPaM(aInternalPaM, xRange))
     466             :             {
     467        1608 :                 SwFmtAnchor aAnchor(pFmt->GetAnchor());
     468        1608 :                 aAnchor.SetAnchor(aInternalPaM.Start());
     469        1608 :                 pFmt->SetFmtAttr(aAnchor);
     470        1608 :             }
     471             :         }
     472        1608 :         break;
     473             :         case RES_CHAIN:
     474          24 :             switch (nMemberId)
     475             :             {
     476             :             case MID_CHAIN_PREVNAME:
     477          12 :                 aPropertyName = UNO_NAME_CHAIN_PREV_NAME;
     478          12 :                 break;
     479             :             case MID_CHAIN_NEXTNAME:
     480          12 :                 aPropertyName = UNO_NAME_CHAIN_NEXT_NAME;
     481          12 :                 break;
     482             :             }
     483          24 :             break;
     484             :         case RES_TEXT_VERT_ADJUST:
     485        2302 :             aPropertyName = UNO_NAME_TEXT_VERT_ADJUST;
     486        2302 :             break;
     487             :         }
     488             : 
     489       29218 :         if (!aPropertyName.isEmpty())
     490             :         {
     491             :             // Position/size should be the text position/size, not the shape one as-is.
     492       18146 :             if (bAdjustX || bAdjustY || bAdjustSize)
     493             :             {
     494        7858 :                 Rectangle aRect = getTextRectangle(pShape, /*bAbsolute=*/false);
     495        7858 :                 if (!aRect.IsEmpty())
     496             :                 {
     497        7766 :                     if (bAdjustX || bAdjustY)
     498             :                     {
     499             :                         sal_Int32 nValue;
     500        4052 :                         if (aValue >>= nValue)
     501             :                         {
     502        4052 :                             if (bAdjustX)
     503        2026 :                                 nValue += TWIPS_TO_MM(aRect.getX());
     504        2026 :                             else if (bAdjustY)
     505        2026 :                                 nValue += TWIPS_TO_MM(aRect.getY());
     506        4052 :                             aValue <<= nValue;
     507        4052 :                         }
     508             :                     }
     509        3714 :                     else if (bAdjustSize)
     510             :                     {
     511        3714 :                         awt::Size aSize(TWIPS_TO_MM(aRect.getWidth()), TWIPS_TO_MM(aRect.getHeight()));
     512        3714 :                         aValue <<= aSize;
     513             :                     }
     514             :                 }
     515             :             }
     516             : 
     517             :             uno::Reference<beans::XPropertySet> const xPropertySet(
     518       18146 :                 SwXTextFrame::CreateXTextFrame(*pFmt->GetDoc(), pFmt),
     519       18146 :                 uno::UNO_QUERY);
     520       18170 :             xPropertySet->setPropertyValue(aPropertyName, aValue);
     521       29218 :         }
     522       83134 :     }
     523             : }
     524             : 
     525        7368 : void SwTextBoxHelper::saveLinks(const SwFrmFmts& rFormats, std::map<const SwFrmFmt*, const SwFrmFmt*>& rLinks)
     526             : {
     527       31332 :     for (size_t i = 0; i < rFormats.size(); ++i)
     528             :     {
     529       23964 :         SwFrmFmt* pFmt = rFormats[i];
     530       23964 :         if (pFmt->Which() != RES_DRAWFRMFMT)
     531       13270 :             continue;
     532       10694 :         if (SwFrmFmt* pTextBox = findTextBox(pFmt))
     533        4012 :             rLinks[pFmt] = pTextBox;
     534             :     }
     535        7368 : }
     536             : 
     537         840 : void SwTextBoxHelper::resetLink(SwFrmFmt* pShape, std::map<const SwFrmFmt*, SwFmtCntnt>& rMap)
     538             : {
     539         840 :     if (pShape->Which() == RES_DRAWFRMFMT)
     540             :     {
     541         370 :         if (pShape->GetCntnt().GetCntntIdx())
     542         188 :             rMap.insert(std::make_pair(pShape, pShape->GetCntnt()));
     543         370 :         pShape->ResetFmtAttr(RES_CNTNT);
     544             :     }
     545         840 : }
     546             : 
     547        7368 : void SwTextBoxHelper::restoreLinks(std::set<_ZSortFly>& rOld, std::vector<SwFrmFmt*>& rNew, SavedLink& rSavedLinks, SavedContent& rOldContent)
     548             : {
     549        7368 :     size_t i = 0;
     550        8208 :     for (std::set<_ZSortFly>::iterator aSetIt = rOld.begin(); aSetIt != rOld.end(); ++aSetIt, ++i)
     551             :     {
     552         840 :         SavedLink::iterator aTextBoxIt = rSavedLinks.find(aSetIt->GetFmt());
     553         840 :         if (aTextBoxIt != rSavedLinks.end())
     554             :         {
     555         188 :             size_t j = 0;
     556         952 :             for (std::set<_ZSortFly>::iterator aSetJt = rOld.begin(); aSetJt != rOld.end(); ++aSetJt, ++j)
     557             :             {
     558         764 :                 if (aSetJt->GetFmt() == aTextBoxIt->second)
     559         188 :                     rNew[i]->SetFmtAttr(rNew[j]->GetCntnt());
     560             :             }
     561             :         }
     562         840 :         if (rOldContent.find(aSetIt->GetFmt()) != rOldContent.end())
     563         188 :             const_cast<SwFrmFmt*>(aSetIt->GetFmt())->SetFmtAttr(rOldContent[aSetIt->GetFmt()]);
     564             :     }
     565        7368 : }
     566             : 
     567         578 : void SwTextBoxHelper::syncFlyFrmAttr(SwFrmFmt& rShape, SfxItemSet& rSet)
     568             : {
     569         578 :     if (SwFrmFmt* pFmt = findTextBox(&rShape))
     570             :     {
     571          12 :         SfxItemSet aTextBoxSet(pFmt->GetDoc()->GetAttrPool(), aFrmFmtSetRange);
     572             : 
     573          24 :         SfxItemIter aIter(rSet);
     574          12 :         sal_uInt16 nWhich = aIter.GetCurItem()->Which();
     575           0 :         do
     576             :         {
     577          12 :             switch (nWhich)
     578             :             {
     579             :             case RES_VERT_ORIENT:
     580             :             {
     581           6 :                 const SwFmtVertOrient& rOrient = static_cast<const SwFmtVertOrient&>(*aIter.GetCurItem());
     582           6 :                 SwFmtVertOrient aOrient(rOrient);
     583             : 
     584           6 :                 Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
     585           6 :                 if (!aRect.IsEmpty())
     586           6 :                     aOrient.SetPos(aOrient.GetPos() + aRect.getY());
     587             : 
     588           6 :                 aTextBoxSet.Put(aOrient);
     589             :             }
     590           6 :             break;
     591             :             case RES_HORI_ORIENT:
     592             :             {
     593           0 :                 const SwFmtHoriOrient& rOrient = static_cast<const SwFmtHoriOrient&>(*aIter.GetCurItem());
     594           0 :                 SwFmtHoriOrient aOrient(rOrient);
     595             : 
     596           0 :                 Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
     597           0 :                 if (!aRect.IsEmpty())
     598           0 :                     aOrient.SetPos(aOrient.GetPos() + aRect.getX());
     599             : 
     600           0 :                 aTextBoxSet.Put(aOrient);
     601             :             }
     602           0 :             break;
     603             :             case RES_FRM_SIZE:
     604             :             {
     605             :                 // In case the shape got resized, then we need to adjust both
     606             :                 // the position and the size of the textbox (e.g. larger
     607             :                 // rounded edges of a rectangle -> need to push right/down the
     608             :                 // textbox).
     609           6 :                 SwFmtVertOrient aVertOrient(rShape.GetVertOrient());
     610          12 :                 SwFmtHoriOrient aHoriOrient(rShape.GetHoriOrient());
     611          12 :                 SwFmtFrmSize aSize(pFmt->GetFrmSize());
     612             : 
     613           6 :                 Rectangle aRect = getTextRectangle(&rShape, /*bAbsolute=*/false);
     614           6 :                 if (!aRect.IsEmpty())
     615             :                 {
     616           6 :                     aVertOrient.SetPos(aVertOrient.GetPos() + aRect.getY());
     617           6 :                     aTextBoxSet.Put(aVertOrient);
     618             : 
     619           6 :                     aHoriOrient.SetPos(aHoriOrient.GetPos() + aRect.getX());
     620           6 :                     aTextBoxSet.Put(aHoriOrient);
     621             : 
     622           6 :                     aSize.SetWidth(aRect.getWidth());
     623           6 :                     aSize.SetHeight(aRect.getHeight());
     624           6 :                     aTextBoxSet.Put(aSize);
     625           6 :                 }
     626             :             }
     627           6 :             break;
     628             :             default:
     629             :                 SAL_WARN("sw.core", "SwTextBoxHelper::syncFlyFrmAttr: unhandled which-id: " << nWhich);
     630           0 :                 break;
     631             :             }
     632             : 
     633          12 :             if (aIter.IsAtEnd())
     634          12 :                 break;
     635             :         }
     636           0 :         while (0 != (nWhich = aIter.NextItem()->Which()));
     637             : 
     638          12 :         if (aTextBoxSet.Count())
     639          24 :             pFmt->GetDoc()->SetFlyFrmAttr(*pFmt, aTextBoxSet);
     640             :     }
     641         848 : }
     642             : 
     643             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10