summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Luth <justin_luth@sil.org>2015-06-18 09:40:29 +0300
committerMiklos Vajna <vmiklos@collabora.co.uk>2015-06-26 14:26:48 +0000
commit976add10b35e482251ed4c75957baeb6811e6e2c (patch)
tree83464d756b0064ca738f2d8ed6ff0bbcfb425b53
parent4cd3f9a7749b8ef285012a59d031dc9f2e4b5e43 (diff)
tdf#87348 allow non-sequentially processed textboxes to be linked
The existing code design ONLY allowed textboxes to be linked if they were basically processed sequentially or reverse sequentially. It appears that the processing is actually based on the order that the textboxes were created, which is usually sequential but not necessarily. Change-Id: Ieb7b37d4cbd4b3a5b5d474803abccfa198a5864b Reviewed-on: https://gerrit.libreoffice.org/16353 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Justin Luth <justin_luth@sil.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx114
1 files changed, 48 insertions, 66 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index ff6ce1d8b3bf..38a4c075b116 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -2449,91 +2449,73 @@ static uno::Any lcl_getGrabBagValue( const uno::Sequence<beans::PropertyValue>&
//Link the text frames.
void DomainMapper_Impl::ChainTextFrames()
{
- if( 0 == m_vTextFramesForChaining.size() )
+ //can't link textboxes if there are not even two of them...
+ if( 2 > m_vTextFramesForChaining.size() )
return ;
+ struct TextFramesForChaining {
+ css::uno::Reference< css::drawing::XShape > xShape;
+ sal_Int32 nId;
+ sal_Int32 nSeq;
+ TextFramesForChaining(): xShape(0), nId(0), nSeq(0) {}
+ } ;
+ typedef std::map <OUString, TextFramesForChaining> ChainMap;
+
try
{
- 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
+ ChainMap aTextFramesForChainingHelper;
OUString sChainNextName("ChainNextName");
- OUString sChainPrevName("ChainPrevName");
- for( std::vector<uno::Reference< drawing::XShape > >::iterator outer_itr = m_vTextFramesForChaining.begin();
- outer_itr != m_vTextFramesForChaining.end(); )
+ //learn about ALL of the textboxes and their chaining values first - because frames are processed in no specific order.
+ std::vector<uno::Reference< drawing::XShape > >::iterator iter;
+ for( iter = m_vTextFramesForChaining.begin(); iter != m_vTextFramesForChaining.end(); ++iter )
{
- bool 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;
- uno::Reference<lang::XServiceInfo> xServiceInfo1(xPropertySet1, uno::UNO_QUERY);
- if (xServiceInfo1->supportsService("com.sun.star.text.TextFrame"))
+ uno::Reference<text::XTextContent> xTextContent(*iter, uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ uno::Reference<lang::XServiceInfo> xServiceInfo(xPropertySet, uno::UNO_QUERY);
+
+ TextFramesForChaining aChainStruct = TextFramesForChaining();
+ OUString sShapeName;
+
+ if ( xServiceInfo->supportsService("com.sun.star.text.TextFrame") )
{
- xPropertySet1->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag1;
- xPropertySet1->getPropertyValue("LinkDisplayName") >>= sName1;
+ xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
+ xPropertySet->getPropertyValue("LinkDisplayName") >>= sShapeName;
}
else
{
- xPropertySet1->getPropertyValue("InteropGrabBag") >>= aGrabBag1;
- xPropertySet1->getPropertyValue("ChainName") >>= sName1;
+ xPropertySet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
+ xPropertySet->getPropertyValue("ChainName") >>= sShapeName;
}
- 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;
- uno::Reference<lang::XServiceInfo> xServiceInfo2(xPropertySet1, uno::UNO_QUERY);
- if (xServiceInfo2->supportsService("com.sun.star.text.TextFrame"))
- {
- xPropertySet2->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag2;
- xPropertySet2->getPropertyValue("LinkDisplayName") >>= sName2;
- }
- else
- {
- xPropertySet2->getPropertyValue("InteropGrabBag") >>= aGrabBag2;
- xPropertySet2->getPropertyValue("ChainName") >>= sName2;
- }
+ lcl_getGrabBagValue( aGrabBag, "Txbx-Id") >>= aChainStruct.nId;
+ lcl_getGrabBagValue( aGrabBag, "Txbx-Seq") >>= aChainStruct.nSeq;
+ aChainStruct.xShape = *iter;
+ aTextFramesForChainingHelper[sShapeName] = aChainStruct;
+ }
- lcl_getGrabBagValue( aGrabBag2, "Txbx-Id") >>= nTxbxId2;
- lcl_getGrabBagValue( aGrabBag2, "Txbx-Seq") >>= nTxbxSeq2;
+ //TODO: Perhaps allow reverse sequences when mso-layout-flow-alt = "bottom-to-top"
+ const sal_Int32 nDirection = 1;
- if ( nTxbxId1 == nTxbxId2 )
+ //Finally - go through and attach the chains based on matching ID and incremented sequence number (dml-style).
+ for (ChainMap::iterator outer_iter= aTextFramesForChainingHelper.begin(); outer_iter != aTextFramesForChainingHelper.end(); ++outer_iter)
+ {
+ for (ChainMap::iterator inner_iter=aTextFramesForChainingHelper.begin(); inner_iter != aTextFramesForChainingHelper.end(); ++inner_iter)
{
- //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 ) )
+ if ( inner_iter->second.nId == outer_iter->second.nId )
{
- 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 ( inner_iter->second.nSeq == ( outer_iter->second.nSeq + nDirection ) )
+ {
+ uno::Reference<text::XTextContent> xTextContent(outer_iter->second.xShape, uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY);
+
+ //The reverse chaining happens automatically, so only one direction needs to be set
+ xPropertySet->setPropertyValue(sChainNextName, uno::makeAny(inner_iter->first));
+ break ; //there cannot be more than one next frame
+ }
}
}
- }
- 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
}