sw/Library_sw.mk | 1 sw/inc/cmdid.h | 1 sw/inc/doc.hxx | 4 sw/inc/textboxhelper.hxx | 53 ++++++ sw/inc/unoprnms.hxx | 1 sw/source/core/doc/docfly.cxx | 23 ++ sw/source/core/doc/textboxhelper.cxx | 279 +++++++++++++++++++++++++++++++++ sw/source/core/unocore/unocoll.cxx | 12 + sw/source/core/unocore/unodraw.cxx | 40 ++++ sw/source/core/unocore/unomap.cxx | 1 sw/source/core/unocore/unoobj2.cxx | 9 + sw/source/core/unocore/unoportenum.cxx | 14 + 12 files changed, 426 insertions(+), 12 deletions(-)
New commits: commit 73e4257ec8eb2079052e2a7d9aef1949c989fb2a Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:08:33 2014 +0200 SwXTextPortionEnumeration: do not expose inline anchored textboxes Change-Id: Id4aecd49e29f6aa8347be4d9e3e8f0e73f7c5a21 diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx index c6a7bc4..887b84f 100644 --- a/sw/source/core/unocore/unoportenum.cxx +++ b/sw/source/core/unocore/unoportenum.cxx @@ -28,6 +28,7 @@ #include <ndtxt.hxx> #include <unocrsr.hxx> #include <docary.hxx> +#include <textboxhelper.hxx> #include <tox.hxx> #include <unomid.h> #include <unoparaframeenum.hxx> @@ -43,6 +44,7 @@ #include <fmtanchr.hxx> #include <fmtrfmrk.hxx> #include <frmfmt.hxx> +#include <fmtflcnt.hxx> #include <unoidx.hxx> #include <unocoll.hxx> #include <redline.hxx> @@ -687,7 +689,8 @@ lcl_ExportHints( const sal_Int32 nCurrentIndex, const bool bRightMoveForbidden, bool & o_rbCursorMoved, - sal_Int32 & o_rNextAttrPosition ) + sal_Int32 & o_rNextAttrPosition, + std::list<SwFrmFmt*>& rTextBoxes) { // if the attribute has a dummy character, then xRef is set (except META) // otherwise, the portion for the attribute is inserted into rPortions! @@ -856,6 +859,11 @@ lcl_ExportHints( pUnoCrsr->Right(1,CRSR_SKIP_CHARS,false,false); if( *pUnoCrsr->GetMark() == *pUnoCrsr->GetPoint() ) break; // Robust #i81708 content in covered cells + + // Do not expose inline anchored textboxes. + if (std::find(rTextBoxes.begin(), rTextBoxes.end(), pAttr->GetFlyCnt().GetFrmFmt()) != rTextBoxes.end()) + break; + pUnoCrsr->Exchange(); xRef = new SwXTextPortion( pUnoCrsr, xParent, PORTION_FRAME); } @@ -1234,6 +1242,8 @@ static void lcl_CreatePortions( PortionStack_t PortionStack; PortionStack.push( PortionList_t(&i_rPortions, (const SwTxtAttr *)0) ); + std::list<SwFrmFmt*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); + bool bAtEnd( false ); while (!bAtEnd) // every iteration consumes at least current character! { @@ -1284,7 +1294,7 @@ static void lcl_CreatePortions( // N.B.: side-effects nNextAttrIndex, bCursorMoved; may move cursor xRef = lcl_ExportHints(PortionStack, i_xParentText, pUnoCrsr, pHints, i_nStartPos, i_nEndPos, nCurrentIndex, bAtEnd, - bCursorMoved, nNextAttrIndex); + bCursorMoved, nNextAttrIndex, aTextBoxes); if (PortionStack.empty()) { OSL_FAIL("CreatePortions: stack underflow"); commit d2aa5fc49a5c7669aac5afa05ac99bb29c78971f Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:08:16 2014 +0200 SwXFrameEnumeration: ignore textboxes Change-Id: I6b37e904898c8b57e619443035ca271b411f5f00 diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx index 3ecae22..a6e2831 100644 --- a/sw/source/core/unocore/unocoll.cxx +++ b/sw/source/core/unocore/unocoll.cxx @@ -49,6 +49,7 @@ #include <unofield.hxx> #include <unoidx.hxx> #include <unoframe.hxx> +#include <textboxhelper.hxx> #include <unofootnote.hxx> #include <vcl/svapp.hxx> #include <fmtcntnt.hxx> @@ -1087,12 +1088,15 @@ SwXFrameEnumeration<T>::SwXFrameEnumeration(const SwDoc* const pDoc) ::std::insert_iterator<frmcontainer_t> pInserter = ::std::insert_iterator<frmcontainer_t>(m_aFrames, m_aFrames.begin()); // #i104937# SwFrmFmt* pFmt( 0 ); + + std::list<SwFrmFmt*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); + for( sal_uInt16 i = 0; i < nSize; ++i ) // for(SwFrmFmt* pFmt = (*pFmts)[0]; pFmt < pFmtsEnd; ++pFmt) { // #i104937# pFmt = (*pFmts)[i]; - if(pFmt->Which() != RES_FLYFRMFMT) + if(pFmt->Which() != RES_FLYFRMFMT || std::find(aTextBoxes.begin(), aTextBoxes.end(), pFmt) != aTextBoxes.end()) continue; const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx(); if(!pIdx || !pIdx->GetNodes().IsDocNodes()) commit b12bb0fb2e8db6e0f2092163d9fe46dc990132dd Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:08:00 2014 +0200 SwXFrames::getByIndex: ignore textboxes Change-Id: I58a8c3cf5e0384f68a9259b3a1575a201436057e diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index bccd5dd..8bab97a 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1233,7 +1233,7 @@ public: /** Access to frames. Iterate over Flys - forr Basic-Collections. */ sal_uInt16 GetFlyCount( FlyCntType eType = FLYCNTTYPE_ALL, bool bIgnoreTextBoxes = false ) const; - SwFrmFmt* GetFlyNum(sal_uInt16 nIdx, FlyCntType eType = FLYCNTTYPE_ALL); + SwFrmFmt* GetFlyNum(sal_uInt16 nIdx, FlyCntType eType = FLYCNTTYPE_ALL, bool bIgnoreTextBoxes = false ); // Copy formats in own arrays and return them. SwFrmFmt *CopyFrmFmt ( const SwFrmFmt& ); diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx index c657db0..4755251 100644 --- a/sw/source/core/doc/docfly.cxx +++ b/sw/source/core/doc/docfly.cxx @@ -120,16 +120,25 @@ sal_uInt16 SwDoc::GetFlyCount( FlyCntType eType, bool bIgnoreTextBoxes ) const } /// @attention If you change this, also update SwXFrameEnumeration in unocoll. -SwFrmFmt* SwDoc::GetFlyNum( sal_uInt16 nIdx, FlyCntType eType ) +SwFrmFmt* SwDoc::GetFlyNum( sal_uInt16 nIdx, FlyCntType eType, bool bIgnoreTextBoxes ) { SwFrmFmts& rFmts = *GetSpzFrmFmts(); SwFrmFmt* pRetFmt = 0; sal_uInt16 nSize = rFmts.size(); const SwNodeIndex* pIdx; sal_uInt16 nCount = 0; + + std::list<SwFrmFmt*> aTextBoxes; + if (bIgnoreTextBoxes) + aTextBoxes = SwTextBoxHelper::findTextBoxes(this); + for( sal_uInt16 i = 0; !pRetFmt && i < nSize; ++i ) { SwFrmFmt* pFlyFmt = rFmts[ i ]; + + if (bIgnoreTextBoxes && std::find(aTextBoxes.begin(), aTextBoxes.end(), pFlyFmt) != aTextBoxes.end()) + continue; + if( RES_FLYFRMFMT == pFlyFmt->Which() && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) && pIdx->GetNodes().IsDocNodes() diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx index c73d91e..3ecae22 100644 --- a/sw/source/core/unocore/unocoll.cxx +++ b/sw/source/core/unocore/unocoll.cxx @@ -1200,7 +1200,8 @@ uno::Any SwXFrames::getByIndex(sal_Int32 nIndex) throw uno::RuntimeException(); if(nIndex < 0 || nIndex >= USHRT_MAX) throw IndexOutOfBoundsException(); - SwFrmFmt* pFmt = GetDoc()->GetFlyNum(static_cast<sal_uInt16>(nIndex), eType); + // Ignore TextBoxes for TextFrames. + SwFrmFmt* pFmt = GetDoc()->GetFlyNum(static_cast<sal_uInt16>(nIndex), eType, /*bIgnoreTextBoxes=*/eType == FLYCNTTYPE_FRM); if(!pFmt) throw IndexOutOfBoundsException(); return lcl_UnoWrapFrame(pFmt, eType); commit 23a12e015b8e9ea36eace51c0d1a982313828478 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:07:43 2014 +0200 SwXFrames::getCount: ignore TextFrames, which are TextBoxes Change-Id: I12d2912f566a31e36f6d091d554106b927abb9c9 diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index 4e833d8..bccd5dd 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1232,7 +1232,7 @@ public: /** Access to frames. Iterate over Flys - forr Basic-Collections. */ - sal_uInt16 GetFlyCount( FlyCntType eType = FLYCNTTYPE_ALL) const; + sal_uInt16 GetFlyCount( FlyCntType eType = FLYCNTTYPE_ALL, bool bIgnoreTextBoxes = false ) const; SwFrmFmt* GetFlyNum(sal_uInt16 nIdx, FlyCntType eType = FLYCNTTYPE_ALL); // Copy formats in own arrays and return them. diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx index e306eb8..c657db0 100644 --- a/sw/source/core/doc/docfly.cxx +++ b/sw/source/core/doc/docfly.cxx @@ -42,6 +42,7 @@ #include <pagefrm.hxx> #include <rootfrm.hxx> #include <flyfrms.hxx> +#include <textboxhelper.hxx> #include <frmtool.hxx> #include <frmfmt.hxx> #include <ndtxt.hxx> @@ -68,15 +69,24 @@ using namespace ::com::sun::star; -sal_uInt16 SwDoc::GetFlyCount( FlyCntType eType ) const +sal_uInt16 SwDoc::GetFlyCount( FlyCntType eType, bool bIgnoreTextBoxes ) const { const SwFrmFmts& rFmts = *GetSpzFrmFmts(); sal_uInt16 nSize = rFmts.size(); sal_uInt16 nCount = 0; const SwNodeIndex* pIdx; + + std::list<SwFrmFmt*> aTextBoxes; + if (bIgnoreTextBoxes) + aTextBoxes = SwTextBoxHelper::findTextBoxes(this); + for ( sal_uInt16 i = 0; i < nSize; i++) { const SwFrmFmt* pFlyFmt = rFmts[ i ]; + + if (bIgnoreTextBoxes && std::find(aTextBoxes.begin(), aTextBoxes.end(), pFlyFmt) != aTextBoxes.end()) + continue; + if( RES_FLYFRMFMT == pFlyFmt->Which() && 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) && pIdx->GetNodes().IsDocNodes() diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx index 6a6fb94..c73d91e 100644 --- a/sw/source/core/unocore/unocoll.cxx +++ b/sw/source/core/unocore/unocoll.cxx @@ -1188,7 +1188,8 @@ sal_Int32 SwXFrames::getCount(void) throw(uno::RuntimeException, std::exception) SolarMutexGuard aGuard; if(!IsValid()) throw uno::RuntimeException(); - return GetDoc()->GetFlyCount(eType); + // Ignore TextBoxes for TextFrames. + return GetDoc()->GetFlyCount(eType, /*bIgnoreTextBoxes=*/eType == FLYCNTTYPE_FRM); } uno::Any SwXFrames::getByIndex(sal_Int32 nIndex) commit 4782e774e39b57ae431e731f13763c43e6658117 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:07:23 2014 +0200 SwTextBoxHelper::findTextBox: only draw frames can have textboxes Change-Id: I4ff9f87120a9ba392aee205641e17c12cb30649b diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 36c302a..56b4e0e 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -143,13 +143,15 @@ SwFrmFmt* SwTextBoxHelper::findTextBox(SwFrmFmt* pShape) { SwFrmFmt* pRet = 0; - if (pShape->GetAttrSet().HasItem(RES_CNTNT)) + // Only draw frames can have TextBoxes. + if (pShape->Which() == RES_DRAWFRMFMT && pShape->GetAttrSet().HasItem(RES_CNTNT)) { const SwFmtCntnt& rCntnt = pShape->GetCntnt(); SwFrmFmts& rSpzFrmFmts = *pShape->GetDoc()->GetSpzFrmFmts(); for (SwFrmFmts::iterator it = rSpzFrmFmts.begin(); it != rSpzFrmFmts.end(); ++it) { SwFrmFmt* pFmt = *it; + // Only a fly frame can be a TextBox. if (pFmt->Which() == RES_FLYFRMFMT && pFmt->GetAttrSet().HasItem(RES_CNTNT) && pFmt->GetCntnt() == rCntnt) { pRet = pFmt; commit 0f884b27fde424990c1a9c2254258dba8b7efa24 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:07:06 2014 +0200 let SwTextBoxHelper::findTextBoxes() take a const SwDoc Change-Id: Icb1540b93f4117999b755d4d5fd387f1228250aa diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index d3532c0..28f8d71 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -41,7 +41,7 @@ public: static SwFrmFmt* findTextBox(SwFrmFmt* pShape); /// Look up TextFrames in a document, which are in fact TextBoxes. - static std::list<SwFrmFmt*> findTextBoxes(SwDoc* pDoc); + static std::list<SwFrmFmt*> findTextBoxes(const SwDoc* pDoc); /// Count number of shapes in the document, excluding TextBoxes. static sal_Int32 getCount(SdrPage* pPage, std::list<SwFrmFmt*>& rTextBoxes); /// Get a shape by index, excluding TextBoxes. diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index d2cd4d7..36c302a 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -83,12 +83,12 @@ void SwTextBoxHelper::destroy(SwFrmFmt* pShape) } } -std::list<SwFrmFmt*> SwTextBoxHelper::findTextBoxes(SwDoc* pDoc) +std::list<SwFrmFmt*> SwTextBoxHelper::findTextBoxes(const SwDoc* pDoc) { std::list<SwFrmFmt*> aRet; - SwFrmFmts& rSpzFrmFmts = *pDoc->GetSpzFrmFmts(); - for (SwFrmFmts::iterator it = rSpzFrmFmts.begin(); it != rSpzFrmFmts.end(); ++it) + const SwFrmFmts& rSpzFrmFmts = *pDoc->GetSpzFrmFmts(); + for (SwFrmFmts::const_iterator it = rSpzFrmFmts.begin(); it != rSpzFrmFmts.end(); ++it) { SwFrmFmt* pTextBox = findTextBox(*it); if (pTextBox) commit 4721729fba32a02683ecc930b630491599f8c6c5 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:06:48 2014 +0200 SwXParaFrameEnumeration: ignore textboxes Change-Id: Ia4441a06c29447d4a4f4cbe6250248a0f68831f1 diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx index cc43ec6..4660ce1 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -27,6 +27,7 @@ #include <frmfmt.hxx> #include <doc.hxx> #include <IDocumentUndoRedo.hxx> +#include <textboxhelper.hxx> #include <ndtxt.hxx> #include <ndnotxt.hxx> #include <unocrsr.hxx> @@ -181,10 +182,17 @@ void CollectFrameAtNode( SwClient& rClnt, const SwNodeIndex& rIdx, { const SwSortedObjs *pObjs = pCFrm->GetDrawObjs(); if( pObjs ) + { + std::list<SwFrmFmt*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); for( sal_uInt16 i = 0; i < pObjs->Count(); ++i ) { SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); + + // Filter out textboxes, which are not interesting at an UNO level. + if (std::find(aTextBoxes.begin(), aTextBoxes.end(), &rFmt) != aTextBoxes.end()) + continue; + if ( rFmt.GetAnchor().GetAnchorId() == nChkType ) { // create SwDepend and insert into array @@ -199,6 +207,7 @@ void CollectFrameAtNode( SwClient& rClnt, const SwNodeIndex& rIdx, rFrames.push_back(entry); } } + } } else { commit 69578bf06d206e234ea8fd4a5f8331edfd9eb590 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:06:29 2014 +0200 SwXDrawPage::getByIndex(): ignore textboxes Change-Id: I643ca4268e15af1882adb168af152835ef216cd9 diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index bac2dcc..d3532c0 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -14,6 +14,7 @@ #include <com/sun/star/uno/Any.h> #include <com/sun/star/uno/Type.h> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> class SdrPage; class SwFrmFmt; @@ -43,6 +44,8 @@ public: static std::list<SwFrmFmt*> findTextBoxes(SwDoc* pDoc); /// Count number of shapes in the document, excluding TextBoxes. static sal_Int32 getCount(SdrPage* pPage, std::list<SwFrmFmt*>& rTextBoxes); + /// Get a shape by index, excluding TextBoxes. + static css::uno::Any getByIndex(SdrPage* pPage, sal_Int32 nIndex, std::list<SwFrmFmt*>& rTextBoxes) throw(css::lang::IndexOutOfBoundsException); }; #endif // INCLUDED_SW_INC_TEXTBOXHELPER_HXX diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 4671580..d2cd4d7 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -98,19 +98,47 @@ std::list<SwFrmFmt*> SwTextBoxHelper::findTextBoxes(SwDoc* pDoc) return aRet; } +/// If the passed SdrObject is in fact a TextFrame, that is used as a TextBox. +bool lcl_isTextBox(SdrObject* pSdrObject, std::list<SwFrmFmt*>& rTextBoxes) +{ + SwVirtFlyDrawObj* pObject = PTR_CAST(SwVirtFlyDrawObj, pSdrObject); + return pObject && std::find(rTextBoxes.begin(), rTextBoxes.end(), pObject->GetFmt()) != rTextBoxes.end(); +} + sal_Int32 SwTextBoxHelper::getCount(SdrPage* pPage, std::list<SwFrmFmt*>& rTextBoxes) { sal_Int32 nRet = 0; for (size_t i = 0; i < pPage->GetObjCount(); ++i) { - SwVirtFlyDrawObj* pObject = PTR_CAST(SwVirtFlyDrawObj, pPage->GetObj(i)); - if (pObject && std::find(rTextBoxes.begin(), rTextBoxes.end(), pObject->GetFmt()) != rTextBoxes.end()) + if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes)) continue; ++nRet; } return nRet; } +uno::Any SwTextBoxHelper::getByIndex(SdrPage* pPage, sal_Int32 nIndex, std::list<SwFrmFmt*>& rTextBoxes) throw(lang::IndexOutOfBoundsException) +{ + if (nIndex < 0 || nIndex >= getCount(pPage, rTextBoxes)) + throw lang::IndexOutOfBoundsException(); + + SdrObject* pRet = 0; + sal_Int32 nCount = 0; // Current logical index. + for (size_t i = 0; i < pPage->GetObjCount(); ++i) + { + if (lcl_isTextBox(pPage->GetObj(i), rTextBoxes)) + continue; + if (nCount == nIndex) + { + pRet = pPage->GetObj(i); + break; + } + ++nCount; + } + assert(pRet); + return uno::makeAny(uno::Reference<drawing::XShape>(pRet->getUnoShape(), uno::UNO_QUERY)); +} + SwFrmFmt* SwTextBoxHelper::findTextBox(SwFrmFmt* pShape) { SwFrmFmt* pRet = 0; diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index c720e99..2b122ec 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -538,7 +538,11 @@ uno::Any SwXDrawPage::getByIndex(sal_Int32 nIndex) throw lang::IndexOutOfBoundsException(); ((SwXDrawPage*)this)->GetSvxPage(); - return pDrawPage->getByIndex( nIndex ); + std::list<SwFrmFmt*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); + if (aTextBoxes.empty()) + return pDrawPage->getByIndex( nIndex ); + else + return SwTextBoxHelper::getByIndex(pDrawPage->GetSdrPage(), nIndex, aTextBoxes); } uno::Type SwXDrawPage::getElementType(void) throw( uno::RuntimeException, std::exception ) commit f1dae10ca512084a04d08e3f0268723223a92e38 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:06:11 2014 +0200 SwXDrawPage::getCount(): ignore textboxes Change-Id: I579cc0242f6901175162b169813e4465d52952a0 diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index f7750b3..bac2dcc 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -10,10 +10,14 @@ #ifndef INCLUDED_SW_INC_TEXTBOXHELPER_HXX #define INCLUDED_SW_INC_TEXTBOXHELPER_HXX +#include <list> + #include <com/sun/star/uno/Any.h> #include <com/sun/star/uno/Type.h> +class SdrPage; class SwFrmFmt; +class SwDoc; /** * A TextBox is a TextFrame, that is tied to a drawinglayer shape. @@ -34,6 +38,11 @@ public: static void syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, const OUString& rPropertyName, const css::uno::Any& rValue); /// If we have an associated TextFrame, then return that. static SwFrmFmt* findTextBox(SwFrmFmt* pShape); + + /// Look up TextFrames in a document, which are in fact TextBoxes. + static std::list<SwFrmFmt*> findTextBoxes(SwDoc* pDoc); + /// Count number of shapes in the document, excluding TextBoxes. + static sal_Int32 getCount(SdrPage* pPage, std::list<SwFrmFmt*>& rTextBoxes); }; #endif // INCLUDED_SW_INC_TEXTBOXHELPER_HXX diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 85b18b9..4671580 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -18,9 +18,11 @@ #include <unotextbodyhf.hxx> #include <unotextrange.hxx> #include <unomid.h> +#include <dflyobj.hxx> #include <svx/svdoashp.hxx> #include <svx/unopage.hxx> +#include <svx/svdpage.hxx> #include <com/sun/star/table/BorderLine2.hpp> #include <com/sun/star/text/SizeType.hpp> @@ -81,6 +83,34 @@ void SwTextBoxHelper::destroy(SwFrmFmt* pShape) } } +std::list<SwFrmFmt*> SwTextBoxHelper::findTextBoxes(SwDoc* pDoc) +{ + std::list<SwFrmFmt*> aRet; + + SwFrmFmts& rSpzFrmFmts = *pDoc->GetSpzFrmFmts(); + for (SwFrmFmts::iterator it = rSpzFrmFmts.begin(); it != rSpzFrmFmts.end(); ++it) + { + SwFrmFmt* pTextBox = findTextBox(*it); + if (pTextBox) + aRet.push_back(pTextBox); + } + + return aRet; +} + +sal_Int32 SwTextBoxHelper::getCount(SdrPage* pPage, std::list<SwFrmFmt*>& rTextBoxes) +{ + sal_Int32 nRet = 0; + for (size_t i = 0; i < pPage->GetObjCount(); ++i) + { + SwVirtFlyDrawObj* pObject = PTR_CAST(SwVirtFlyDrawObj, pPage->GetObj(i)); + if (pObject && std::find(rTextBoxes.begin(), rTextBoxes.end(), pObject->GetFmt()) != rTextBoxes.end()) + continue; + ++nRet; + } + return nRet; +} + SwFrmFmt* SwTextBoxHelper::findTextBox(SwFrmFmt* pShape) { SwFrmFmt* pRet = 0; diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index b01ae9c..c720e99 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -30,6 +30,7 @@ #include <swunohelper.hxx> #include <textboxhelper.hxx> #include <doc.hxx> +#include <docary.hxx> #include <IDocumentUndoRedo.hxx> #include <fmtcntnt.hxx> #include <fmtflcnt.hxx> @@ -516,7 +517,13 @@ sal_Int32 SwXDrawPage::getCount(void) throw( uno::RuntimeException, std::excepti else { ((SwXDrawPage*)this)->GetSvxPage(); - return pDrawPage->getCount(); + + std::list<SwFrmFmt*> aTextBoxes = SwTextBoxHelper::findTextBoxes(pDoc); + + if (aTextBoxes.empty()) + return pDrawPage->getCount(); + else + return SwTextBoxHelper::getCount(pDrawPage->GetSdrPage(), aTextBoxes); } } commit ae59502b20b52aaf34f8f4d89e354f28a7dbe453 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:05:55 2014 +0200 SwXShape: return the right XText implementaation in the TextBox case Change-Id: Iac31bd4b3b1918f857feff9045df473e9b1d3d2b diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index 0c992dc..f7750b3 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -28,8 +28,8 @@ public: static void create(SwFrmFmt* pShape); /// Destroy a TextBox for a shape. static void destroy(SwFrmFmt* pShape); - /// Get XTextAppend of a shape's TextBox, if there is any. - static css::uno::Any getXTextAppend(SwFrmFmt* pShape, const css::uno::Type& rType); + /// Get interface of a shape's TextBox, if there is any. + static css::uno::Any queryInterface(SwFrmFmt* pShape, const css::uno::Type& rType); /// Sync property of TextBox with the one of the shape. static void syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, const OUString& rPropertyName, const css::uno::Any& rValue); /// If we have an associated TextFrame, then return that. diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index faadb5f..85b18b9 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -103,18 +103,29 @@ SwFrmFmt* SwTextBoxHelper::findTextBox(SwFrmFmt* pShape) return pRet; } -uno::Any SwTextBoxHelper::getXTextAppend(SwFrmFmt* pShape, const uno::Type& rType) +template < typename T > +void lcl_queryInterface(SwFrmFmt* pShape, uno::Any& rAny) +{ + if (SwFrmFmt* pFmt = SwTextBoxHelper::findTextBox(pShape)) + { + uno::Reference<T> xInterface(static_cast<cppu::OWeakObject*>(SwXFrames::GetObject(*pFmt, FLYCNTTYPE_FRM)), uno::UNO_QUERY); + rAny <<= xInterface; + } +} + +uno::Any SwTextBoxHelper::queryInterface(SwFrmFmt* pShape, const uno::Type& rType) { uno::Any aRet; if (rType == cppu::UnoType<css::text::XTextAppend>::get()) { - if (SwFrmFmt* pFmt = findTextBox(pShape)) - { - uno::Reference<text::XTextAppend> xTextAppend(static_cast<cppu::OWeakObject*>(SwXFrames::GetObject(*pFmt, FLYCNTTYPE_FRM)), uno::UNO_QUERY); - aRet <<= xTextAppend; - } + lcl_queryInterface<text::XTextAppend>(pShape, aRet); } + else if (rType == cppu::UnoType<css::text::XText>::get()) + { + lcl_queryInterface<text::XText>(pShape, aRet); + } + return aRet; } diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index e506cd2..b01ae9c 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -975,7 +975,7 @@ SwXShape::~SwXShape() uno::Any SwXShape::queryInterface( const uno::Type& aType ) throw( uno::RuntimeException, std::exception ) { - uno::Any aRet = SwTextBoxHelper::getXTextAppend(GetFrmFmt(), aType); + uno::Any aRet = SwTextBoxHelper::queryInterface(GetFrmFmt(), aType); if (aRet.hasValue()) return aRet; commit f8ef170acf5bc01820c986428c7bec419e6884b6 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:05:36 2014 +0200 SwXShape: allow setting TextBox property to false Change-Id: I23d79fc3f5c020c86296bfc84bb0824e1ca68228 diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index 93a459d..0c992dc 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -26,6 +26,8 @@ class SwTextBoxHelper public: /// Create a TextBox for a shape. static void create(SwFrmFmt* pShape); + /// Destroy a TextBox for a shape. + static void destroy(SwFrmFmt* pShape); /// Get XTextAppend of a shape's TextBox, if there is any. static css::uno::Any getXTextAppend(SwFrmFmt* pShape, const css::uno::Type& rType); /// Sync property of TextBox with the one of the shape. diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 9937778..faadb5f 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -65,6 +65,22 @@ void SwTextBoxHelper::create(SwFrmFmt* pShape) } } +void SwTextBoxHelper::destroy(SwFrmFmt* pShape) +{ + // If a TextBox was enabled previously + if (pShape->GetAttrSet().HasItem(RES_CNTNT)) + { + SwFrmFmt* pFmt = findTextBox(pShape); + + // Unlink the TextBox's text range from the original shape. + pShape->ResetFmtAttr(RES_CNTNT); + + // Delete the associated TextFrame. + if (pFmt) + pShape->GetDoc()->DelLayoutFmt(pFmt); + } +} + SwFrmFmt* SwTextBoxHelper::findTextBox(SwFrmFmt* pShape) { SwFrmFmt* pRet = 0; diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index 1c03330..e506cd2 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -1182,9 +1182,10 @@ void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& a { bool bValue; aValue >>= bValue; - // If TextBox is to be enabled. if (bValue) SwTextBoxHelper::create(pFmt); + else + SwTextBoxHelper::destroy(pFmt); } // #i28749# commit 0baec970707fb6e884b028bbe2ffedb441e296eb Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:05:16 2014 +0200 SwTextBoxHelper::syncProperty(): avoid crash on not-yet-inserted shape Change-Id: I3308ba685b4066ea6849e8002e9d98cc5264c368 diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index ec27548..9937778 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -105,6 +105,10 @@ uno::Any SwTextBoxHelper::getXTextAppend(SwFrmFmt* pShape, const uno::Type& rTyp void SwTextBoxHelper::syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 nMemberId, const OUString& rPropertyName, const css::uno::Any& rValue) { + // No shape yet? Then nothing to do, initial properties are set by create(). + if (!pShape) + return; + uno::Any aValue(rValue); nMemberId &= ~CONVERT_TWIPS; commit f1ada85a95268f1276608ff25c761f2aee77dcb6 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:04:57 2014 +0200 SwXShape: new bool TextBox property Change-Id: Iae588c817ea17b6b2c2d3f2818ee5f94ed6f4e96 diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index a7674e1..c27ceb9 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -813,6 +813,7 @@ #define FN_SHAPE_STARTPOSITION_IN_HORI_L2R (FN_PARAM2+25) #define FN_SHAPE_ENDPOSITION_IN_HORI_L2R (FN_PARAM2+26) #define FN_PARAM_PAM (FN_PARAM2+27) /* Point and Mark */ +#define FN_TEXT_BOX (FN_PARAM2+28) /* TextBox Property*/ // Status: not more than 19! #define FN_STAT_PAGE (FN_STAT + 1) diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index 65ba9cf..93a459d 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -30,6 +30,8 @@ public: static css::uno::Any getXTextAppend(SwFrmFmt* pShape, const css::uno::Type& rType); /// Sync property of TextBox with the one of the shape. static void syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, const OUString& rPropertyName, const css::uno::Any& rValue); + /// If we have an associated TextFrame, then return that. + static SwFrmFmt* findTextBox(SwFrmFmt* pShape); }; #endif // INCLUDED_SW_INC_TEXTBOXHELPER_HXX diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 63dfe4a..bed1254 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -65,6 +65,7 @@ #define UNO_NAME_FOOTER_LEFT_MARGIN "FooterLeftMargin" #define UNO_NAME_FOOTER_RIGHT_MARGIN "FooterRightMargin" #define UNO_NAME_TEXT_RANGE "TextRange" +#define UNO_NAME_TEXT_BOX "TextBox" #define UNO_NAME_NAME "Name" #define UNO_NAME_NUMBERING_ALIGNMENT "NumberingAlignment" #define UNO_NAME_BULLET_FONT_NAME "BulletFontName" diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index d7702f7..ec27548 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -65,8 +65,7 @@ void SwTextBoxHelper::create(SwFrmFmt* pShape) } } -// If we have an associated TextFrame, then return that. -SwFrmFmt* lcl_findTextBox(SwFrmFmt* pShape) +SwFrmFmt* SwTextBoxHelper::findTextBox(SwFrmFmt* pShape) { SwFrmFmt* pRet = 0; @@ -94,7 +93,7 @@ uno::Any SwTextBoxHelper::getXTextAppend(SwFrmFmt* pShape, const uno::Type& rTyp if (rType == cppu::UnoType<css::text::XTextAppend>::get()) { - if (SwFrmFmt* pFmt = lcl_findTextBox(pShape)) + if (SwFrmFmt* pFmt = findTextBox(pShape)) { uno::Reference<text::XTextAppend> xTextAppend(static_cast<cppu::OWeakObject*>(SwXFrames::GetObject(*pFmt, FLYCNTTYPE_FRM)), uno::UNO_QUERY); aRet <<= xTextAppend; @@ -109,7 +108,7 @@ void SwTextBoxHelper::syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 uno::Any aValue(rValue); nMemberId &= ~CONVERT_TWIPS; - if (SwFrmFmt* pFmt = lcl_findTextBox(pShape)) + if (SwFrmFmt* pFmt = findTextBox(pShape)) { bool bSync = false; bool bAdjustX = false; diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index 20a14cf..1c03330 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -1178,6 +1178,15 @@ void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& a delete pInternalPam; } } + else if (pEntry->nWID == FN_TEXT_BOX) + { + bool bValue; + aValue >>= bValue; + // If TextBox is to be enabled. + if (bValue) + SwTextBoxHelper::create(pFmt); + + } // #i28749# else if ( FN_SHAPE_POSITION_LAYOUT_DIR == pEntry->nWID ) { @@ -1500,6 +1509,11 @@ uno::Any SwXShape::getPropertyValue(const OUString& rPropertyName) } } } + else if (pEntry->nWID == FN_TEXT_BOX) + { + bool bValue = SwTextBoxHelper::findTextBox(pFmt); + aRet <<= bValue; + } // #i28749# else if ( FN_SHAPE_TRANSFORMATION_IN_HORI_L2R == pEntry->nWID ) { diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx index b2fb907..5a9cb5a 100644 --- a/sw/source/core/unocore/unomap.cxx +++ b/sw/source/core/unocore/unomap.cxx @@ -1394,6 +1394,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s { OUString(UNO_NAME_RELATIVE_HEIGHT_RELATION), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_HEIGHT_RELATION }, { OUString(UNO_NAME_RELATIVE_WIDTH), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get() , PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH }, { OUString(UNO_NAME_RELATIVE_WIDTH_RELATION), RES_FRM_SIZE, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, MID_FRMSIZE_REL_WIDTH_RELATION }, + { OUString(UNO_NAME_TEXT_BOX), FN_TEXT_BOX, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, { OUString(), 0, css::uno::Type(), 0, 0 } }; aMapEntriesArr[nPropertyId] = aShapeMap_Impl; commit 9a7e617eb30c8a475ccfc1af8bf3bee741a74fbf Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:04:23 2014 +0200 SwXShape: invoke SwTextBoxHelper For now, only in queryInterface(), setPropertyValue() and setSize(). It's safe to always call these methods, if they are not relevant, the method will be a NOP. Change-Id: I6efb808f605d47f731819cd971bb66ca251cafb6 diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index ec4e021..b84e9fc 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -202,6 +202,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/core/doc/tblafmt \ sw/source/core/doc/tblcpy \ sw/source/core/doc/tblrwcl \ + sw/source/core/doc/textboxhelper \ sw/source/core/doc/visiturl \ sw/source/core/docnode/cancellablejob \ sw/source/core/docnode/finalthreadmanager \ diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index 19b1c5a..20a14cf 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -28,6 +28,7 @@ #include <unotextrange.hxx> #include <svx/svditer.hxx> #include <swunohelper.hxx> +#include <textboxhelper.hxx> #include <doc.hxx> #include <IDocumentUndoRedo.hxx> #include <fmtcntnt.hxx> @@ -974,7 +975,11 @@ SwXShape::~SwXShape() uno::Any SwXShape::queryInterface( const uno::Type& aType ) throw( uno::RuntimeException, std::exception ) { - uno::Any aRet = SwXShapeBaseClass::queryInterface(aType); + uno::Any aRet = SwTextBoxHelper::getXTextAppend(GetFrmFmt(), aType); + if (aRet.hasValue()) + return aRet; + + aRet = SwXShapeBaseClass::queryInterface(aType); // #i53320# - follow-up of #i31698# // interface drawing::XShape is overloaded. Thus, provide // correct object instance. @@ -1325,6 +1330,8 @@ void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& a else pFmt->SetFmtAttr(aSet); } + // We have a pFmt and a pEntry as well: try to sync TextBox property. + SwTextBoxHelper::syncProperty(pFmt, pEntry->nWID, pEntry->nMemberId, rPropertyName, aValue); } else { @@ -2309,6 +2316,7 @@ void SAL_CALL SwXShape::setSize( const awt::Size& aSize ) { mxShape->setSize( aSize ); } + SwTextBoxHelper::syncProperty(GetFrmFmt(), RES_FRM_SIZE, MID_FRMSIZE_SIZE, "Size", uno::makeAny(aSize)); } // #i31698# // implementation of virtual methods from drawing::XShapeDescriptor commit 72159041cbb70f59017df0b5c90c5fbbfb6b62aa Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue May 27 09:03:51 2014 +0200 Initial SwTextBoxHelper Change-Id: I2674d72a2ba7bf49f102e09ed8435445c9687bb2 diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx new file mode 100644 index 0000000..65ba9cf --- /dev/null +++ b/sw/inc/textboxhelper.hxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_SW_INC_TEXTBOXHELPER_HXX +#define INCLUDED_SW_INC_TEXTBOXHELPER_HXX + +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/uno/Type.h> + +class SwFrmFmt; + +/** + * A TextBox is a TextFrame, that is tied to a drawinglayer shape. + * + * This class provides helper methods to create, query and maintain such + * TextBoxes. + */ +class SwTextBoxHelper +{ +public: + /// Create a TextBox for a shape. + static void create(SwFrmFmt* pShape); + /// Get XTextAppend of a shape's TextBox, if there is any. + static css::uno::Any getXTextAppend(SwFrmFmt* pShape, const css::uno::Type& rType); + /// Sync property of TextBox with the one of the shape. + static void syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, const OUString& rPropertyName, const css::uno::Any& rValue); +}; + +#endif // INCLUDED_SW_INC_TEXTBOXHELPER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx new file mode 100644 index 0000000..d7702f7 --- /dev/null +++ b/sw/source/core/doc/textboxhelper.cxx @@ -0,0 +1,189 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <textboxhelper.hxx> +#include <frmfmt.hxx> +#include <fmtcntnt.hxx> +#include <doc.hxx> +#include <docsh.hxx> +#include <docary.hxx> +#include <unocoll.hxx> +#include <unoframe.hxx> +#include <unotextbodyhf.hxx> +#include <unotextrange.hxx> +#include <unomid.h> + +#include <svx/svdoashp.hxx> +#include <svx/unopage.hxx> + +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/text/SizeType.hpp> +#include <com/sun/star/text/XTextContent.hpp> +#include <com/sun/star/text/XTextDocument.hpp> + +using namespace com::sun::star; + +void SwTextBoxHelper::create(SwFrmFmt* pShape) +{ + // If TextBox wasn't enabled previously + if (!pShape->GetAttrSet().HasItem(RES_CNTNT)) + { + // Create the associated TextFrame and insert it into the document. + uno::Reference<text::XTextContent> xTextFrame(SwXServiceProvider::MakeInstance(SW_SERVICE_TYPE_TEXTFRAME, pShape->GetDoc()), uno::UNO_QUERY); + uno::Reference<text::XTextDocument> xTextDocument(pShape->GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY); + uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(), uno::UNO_QUERY); + xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>()); + + // Initialize properties. + uno::Reference<beans::XPropertySet> xPropertySet(xTextFrame, uno::UNO_QUERY); + uno::Any aEmptyBorder = uno::makeAny(table::BorderLine2()); + xPropertySet->setPropertyValue("TopBorder", aEmptyBorder); + xPropertySet->setPropertyValue("BottomBorder", aEmptyBorder); + xPropertySet->setPropertyValue("LeftBorder", aEmptyBorder); + xPropertySet->setPropertyValue("RightBorder", aEmptyBorder); + + xPropertySet->setPropertyValue("FillTransparence", uno::makeAny(sal_Int32(100))); + + xPropertySet->setPropertyValue("SizeType", uno::makeAny(text::SizeType::FIX)); + + // Link its text range to the original shape. + uno::Reference<text::XTextRange> xTextBox(xTextFrame, uno::UNO_QUERY_THROW); + SwUnoInternalPaM aInternalPaM(*pShape->GetDoc()); + if (sw::XTextRangeToSwPaM(aInternalPaM, xTextBox)) + { + SwAttrSet aSet(pShape->GetAttrSet()); + SwFmtCntnt aCntnt(aInternalPaM.GetNode()->StartOfSectionNode()); + aSet.Put(aCntnt); + pShape->SetFmtAttr(aSet); + } + } +} + +// If we have an associated TextFrame, then return that. +SwFrmFmt* lcl_findTextBox(SwFrmFmt* pShape) +{ + SwFrmFmt* pRet = 0; + + if (pShape->GetAttrSet().HasItem(RES_CNTNT)) + { + const SwFmtCntnt& rCntnt = pShape->GetCntnt(); + SwFrmFmts& rSpzFrmFmts = *pShape->GetDoc()->GetSpzFrmFmts(); + for (SwFrmFmts::iterator it = rSpzFrmFmts.begin(); it != rSpzFrmFmts.end(); ++it) + { + SwFrmFmt* pFmt = *it; + if (pFmt->Which() == RES_FLYFRMFMT && pFmt->GetAttrSet().HasItem(RES_CNTNT) && pFmt->GetCntnt() == rCntnt) + { + pRet = pFmt; + break; + } + } + } + + return pRet; +} + +uno::Any SwTextBoxHelper::getXTextAppend(SwFrmFmt* pShape, const uno::Type& rType) +{ + uno::Any aRet; + + if (rType == cppu::UnoType<css::text::XTextAppend>::get()) + { + if (SwFrmFmt* pFmt = lcl_findTextBox(pShape)) + { + uno::Reference<text::XTextAppend> xTextAppend(static_cast<cppu::OWeakObject*>(SwXFrames::GetObject(*pFmt, FLYCNTTYPE_FRM)), uno::UNO_QUERY); + aRet <<= xTextAppend; + } + } + + return aRet; +} + +void SwTextBoxHelper::syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8 nMemberId, const OUString& rPropertyName, const css::uno::Any& rValue) +{ + uno::Any aValue(rValue); + nMemberId &= ~CONVERT_TWIPS; + + if (SwFrmFmt* pFmt = lcl_findTextBox(pShape)) + { + bool bSync = false; + bool bAdjustX = false; + bool bAdjustY = false; + bool bAdjustSize = false; + switch (nWID) + { + case RES_HORI_ORIENT: + switch (nMemberId) + { + case MID_HORIORIENT_ORIENT: + case MID_HORIORIENT_RELATION: + bSync = true; + break; + case MID_HORIORIENT_POSITION: + bSync = true; + bAdjustX = true; + break; + } + break; + case RES_VERT_ORIENT: + switch (nMemberId) + { + case MID_VERTORIENT_ORIENT: + case MID_VERTORIENT_RELATION: + bSync = true; + break; + case MID_VERTORIENT_POSITION: + bSync = true; + bAdjustY = true; + break; + } + break; + case RES_FRM_SIZE: + bSync = true; + bAdjustSize = true; + break; + } + + if (bSync) + { + // Position/size should be the text position/size, not the shape one as-is. + if (bAdjustX || bAdjustY || bAdjustSize) + { + SdrObjCustomShape* pCustomShape = dynamic_cast<SdrObjCustomShape*>(pShape->FindRealSdrObject()); + if (pCustomShape) + { + Rectangle aRect; + pCustomShape->GetTextBounds(aRect); + + if (bAdjustX || bAdjustY) + { + sal_Int32 nValue; + if (aValue >>= nValue) + { + if (bAdjustX) + nValue = TWIPS_TO_MM(aRect.getX()); + else if (bAdjustY) + nValue = TWIPS_TO_MM(aRect.getY()); + aValue <<= nValue; + } + } + else if (bAdjustSize) + { + awt::Size aSize(TWIPS_TO_MM(aRect.getWidth()), TWIPS_TO_MM(aRect.getHeight())); + aValue <<= aSize; + } + } + } + + uno::Reference<beans::XPropertySet> xPropertySet(static_cast<cppu::OWeakObject*>(SwXFrames::GetObject(*pFmt, FLYCNTTYPE_FRM)), uno::UNO_QUERY); + xPropertySet->setPropertyValue(rPropertyName, aValue); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits