diff options
author | umeshkadam <umesh.kadam@synerzip.com> | 2014-04-18 13:12:53 +0530 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-04-22 12:09:40 +0200 |
commit | 255194801e9eb8e3aaede56837450af35f8313e0 (patch) | |
tree | aa423243a383fc9236c0229ef87d468ac98dddf2 /writerfilter | |
parent | f12237c4c6239428b00dd4885a25bbc3b4f14368 (diff) |
fod#77122 DOCX filter: link between textboxes is not being preserved
Added support for linked textboxes for docx interoperability.
Reviewed on:
https://gerrit.libreoffice.org/9092
Change-Id: I7db4f5a1783afff53c64908d182788b262f5e863
Diffstat (limited to 'writerfilter')
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 103 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.hxx | 2 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.cxx | 3 |
3 files changed, 105 insertions, 3 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 88bcabddb47a..434e9b082ab6 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -59,7 +59,7 @@ #include <com/sun/star/text/ControlCharacter.hpp> #include <com/sun/star/text/XTextColumns.hpp> #include <oox/mathml/import.hxx> - #include <GraphicHelpers.hxx> +#include <GraphicHelpers.hxx> #ifdef DEBUG_DOMAINMAPPER #include <resourcemodel/QNameToString.hxx> @@ -195,7 +195,8 @@ DomainMapper_Impl::DomainMapper_Impl( m_bHasFtnSep(false), m_bIgnoreNextPara(false), m_bIgnoreNextTab(false), - m_bFrameBtLr(false) + m_bFrameBtLr(false), + m_vTextFramesForChaining() { appendTableManager( ); @@ -221,6 +222,7 @@ DomainMapper_Impl::DomainMapper_Impl( DomainMapper_Impl::~DomainMapper_Impl() { + ChainTextFrames(); RemoveLastParagraph( ); getTableManager( ).endLevel(); popTableManager( ); @@ -1775,6 +1777,15 @@ void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape } if(checkBtLrStatus && checkZOredrStatus) break; + + if ( aGrabBag[i].Name == "TxbxHasLink" ) + { + //Chaining of textboxes will happen in ~DomainMapper_Impl + //i.e when all the textboxes are read and all its attributes + //have been set ( basically the Name/LinkedDisplayName ) + //which is set in Graphic Import. + m_vTextFramesForChaining.push_back(xShape); + } } uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY_THROW); @@ -2219,7 +2230,95 @@ void DomainMapper_Impl::SetNumberFormat( const OUString& rCommand, } } +static uno::Any lcl_getGrabBagValue( const uno::Sequence<beans::PropertyValue>& grabBag, OUString name ) +{ + for (int i = 0; i < grabBag.getLength(); ++i) + { + if (grabBag[i].Name == name ) + return grabBag[i].Value ; + } + return uno::Any(); +} + +//Link the text frames. +void DomainMapper_Impl::ChainTextFrames() +{ + if( 0 == m_vTextFramesForChaining.size() ) + return ; + + try + { + bool bIsTxbxChained = false ; + sal_Int32 nTxbxId1 = 0 ; //holds id for the shape in outer loop + sal_Int32 nTxbxId2 = 0 ; //holds id for the shape in inner loop + sal_Int32 nTxbxSeq1 = 0 ; //holds seq number for the shape in outer loop + sal_Int32 nTxbxSeq2 = 0 ; //holds seq number for the shape in inner loop + OUString sName1 ; //holds the text box Name for the shape in outer loop + OUString sName2 ; //holds the text box Name for the shape in outer loop + OUString sChainNextName("ChainNextName"); + OUString sChainPrevName("ChainPrevName"); + + for( std::vector<uno::Reference< drawing::XShape > >::iterator outer_itr = m_vTextFramesForChaining.begin(); + outer_itr != m_vTextFramesForChaining.end(); ) + { + bIsTxbxChained = false ; + uno::Reference<text::XTextContent> xTextContent1(*outer_itr, uno::UNO_QUERY_THROW); + uno::Reference<beans::XPropertySet> xPropertySet1(xTextContent1, uno::UNO_QUERY); + uno::Sequence<beans::PropertyValue> aGrabBag1; + xPropertySet1->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag1; + xPropertySet1->getPropertyValue("LinkDisplayName") >>= sName1; + + lcl_getGrabBagValue( aGrabBag1, "Txbx-Id") >>= nTxbxId1; + lcl_getGrabBagValue( aGrabBag1, "Txbx-Seq") >>= nTxbxSeq1; + + //Check which text box in the document links/(is a link) to this one. + std::vector<uno::Reference< drawing::XShape > >::iterator inner_itr = ( outer_itr + 1 ); + for( ; inner_itr != m_vTextFramesForChaining.end(); ++inner_itr ) + { + uno::Reference<text::XTextContent> xTextContent2(*inner_itr, uno::UNO_QUERY_THROW); + uno::Reference<beans::XPropertySet> xPropertySet2(xTextContent2, uno::UNO_QUERY); + uno::Sequence<beans::PropertyValue> aGrabBag2; + xPropertySet2->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag2; + xPropertySet2->getPropertyValue("LinkDisplayName") >>= sName2; + + lcl_getGrabBagValue( aGrabBag2, "Txbx-Id") >>= nTxbxId2; + lcl_getGrabBagValue( aGrabBag2, "Txbx-Seq") >>= nTxbxSeq2; + if ( nTxbxId1 == nTxbxId2 ) + { + //who connects whom ?? + if ( ( nTxbxSeq1 == ( nTxbxSeq2 + 1 ) ) ) + { + xPropertySet2->setPropertyValue(sChainNextName, uno::makeAny(sName1)); + xPropertySet1->setPropertyValue(sChainPrevName, uno::makeAny(sName2)); + bIsTxbxChained = true ; + break ; //there cannot be more than one previous/next frames + } + else if( (nTxbxSeq2 == ( nTxbxSeq1 + 1 ) )) + { + xPropertySet1->setPropertyValue(sChainNextName, uno::makeAny(sName2)); + xPropertySet2->setPropertyValue(sChainPrevName, uno::makeAny(sName1)); + bIsTxbxChained = true ; + break ; //there cannot be more than one previous/next frames + } + } + } + if( bIsTxbxChained ) + { + //This txt box is no longer needed for chaining since + //there cannot be more than one previous/next frames + outer_itr = m_vTextFramesForChaining.erase(outer_itr); + } + else + ++outer_itr ; + } + m_vTextFramesForChaining.clear(); //clear the vector + } + catch (const uno::Exception& rException) + { + SAL_WARN("writerfilter", "failed. message: " << rException.Message); + } +} uno::Reference< beans::XPropertySet > DomainMapper_Impl::FindOrCreateFieldMaster( const sal_Char* pFieldMasterService, const OUString& rFieldMasterName ) diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index a28636b3b667..842a13b3bb03 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -449,6 +449,7 @@ public: void StartParaMarkerChange( ); void EndParaMarkerChange( ); + void ChainTextFrames(); void RemoveLastParagraph( ); void SetIsLastParagraphInSection( bool bIsLast ); @@ -777,6 +778,7 @@ public: private: void PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType); + std::vector<uno::Reference< drawing::XShape > > m_vTextFramesForChaining ; }; } //namespace dmapper } //namespace writerfilter diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx index 4f73da5584c9..a8ecda389d99 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -2193,7 +2193,8 @@ OOXMLFastContextHandlerShape::lcl_createFastChildContext // OOXMLFastContextHandlerWrapper::lcl_createFastChildContext(), here we // handle the WPS import of shape text, as there the parent context is a // Shape one, so a different situation. - if (Element == static_cast<sal_Int32>(NS_wps | OOXML_txbx)) + if (Element == static_cast<sal_Int32>(NS_wps | OOXML_txbx) || + Element == static_cast<sal_Int32>(NS_wps | OOXML_linkedTxbx) ) sendShape(Element); return xContextHandler; |