include/oox/vml/vmlshape.hxx                      |    1 +
 offapi/com/sun/star/text/BaseFrameProperties.idl  |   10 ++++++++++
 oox/source/vml/vmlshape.cxx                       |   22 ++++++++++++++++++++++
 oox/source/vml/vmltextboxcontext.cxx              |    2 ++
 sw/inc/hintids.hxx                                |    1 +
 sw/inc/unoprnms.hxx                               |    1 +
 sw/qa/extras/ooxmlimport/data/fdo69636.docx       |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx          |   11 +++++++++++
 sw/source/core/bastyp/init.cxx                    |    2 ++
 sw/source/core/unocore/unomap.cxx                 |    2 ++
 sw/source/core/unocore/unoprnms.cxx               |    1 +
 writerfilter/source/dmapper/DomainMapper.cxx      |    3 +++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |   17 ++++++++++++++++-
 writerfilter/source/dmapper/DomainMapper_Impl.hxx |    1 +
 14 files changed, 73 insertions(+), 1 deletion(-)

New commits:
commit 8738ded7bb1bb6262fe1038e310b5110407f4cfa
Author: Miklos Vajna <[email protected]>
Date:   Thu Sep 26 12:21:59 2013 +0200

    fdo#69636 VML import: handle mso-layout-flow-alt shape prop for sw frames
    
    Writer core doesn't support this, and this has been a problem for table
    cells as well. There the workaround we're using for quite a while is to
    do the rotation at a text portion level instead, which results in
    reasonable layout for simple cases. Do the same here.
    
    One additional complexity is that the API between oox and writerfilter
    is a single UNO shape, we get this property in oox, and we have to
    handle it in writerfilter, when the text frame is already attached to
    some text. Kill this problem by adding a FrameInteropGrabBag for sw text
    frames: it's useful anyway, and then we can pass around this property
    inside the grab bag.
    
    Change-Id: Idb5ec83b5cbdde8f29d15b2cebfad24226bb6507

diff --git a/include/oox/vml/vmlshape.hxx b/include/oox/vml/vmlshape.hxx
index 345210b..b40e211 100644
--- a/include/oox/vml/vmlshape.hxx
+++ b/include/oox/vml/vmlshape.hxx
@@ -101,6 +101,7 @@ struct OOX_DLLPUBLIC ShapeTypeModel
     OUString maWrapDistanceRight;        ///< Distance from the right side of 
the shape to the text that wraps around it.
     OUString maWrapDistanceTop;          ///< Distance from the top of the 
shape to the text that wraps around it.
     OUString maWrapDistanceBottom;       ///< Distance from the bottom of the 
shape to the text that wraps around it.
+    OUString maLayoutFlowAlt; ///< Specifies the alternate layout flow for 
text in textboxes.
 
     explicit            ShapeTypeModel();
 
diff --git a/offapi/com/sun/star/text/BaseFrameProperties.idl 
b/offapi/com/sun/star/text/BaseFrameProperties.idl
index ff00e2c..edbb1cc 100644
--- a/offapi/com/sun/star/text/BaseFrameProperties.idl
+++ b/offapi/com/sun/star/text/BaseFrameProperties.idl
@@ -326,6 +326,16 @@ published service BaseFrameProperties
          */
         [optional, property] short ShadowTransparence;
 
+        /** Grab bag of frame properties, used as a string-any map for interim 
interop purposes.
+
+            @since LibreOffice 4.2
+
+            <p>This property is intentionally not handled by the ODF filter. 
Any
+            member that should be handled there should be first moved out from 
this grab
+            bag to a separate property.</p>
+        */
+        [optional, property] sequence<com::sun::star::beans::PropertyValue> 
FrameInteropGrabBag;
+
 };
 
 
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 26cc704..b50551d 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -554,6 +554,28 @@ Reference< XShape > SimpleShape::implConvertAndInsert( 
const Reference< XShapes
             PropertySet( xShape ).setAnyProperty( PROP_RightBorderDistance, 
makeAny( sal_Int32( getTextBox()->borderDistanceRight )));
             PropertySet( xShape ).setAnyProperty( PROP_BottomBorderDistance, 
makeAny( sal_Int32( getTextBox()->borderDistanceBottom )));
         }
+        if (!maTypeModel.maLayoutFlowAlt.isEmpty())
+        {
+            // Can't handle this property here, as the frame is not attached 
yet: pass it to writerfilter.
+            uno::Reference<beans::XPropertySet> xPropertySet(xShape, 
uno::UNO_QUERY);
+            uno::Sequence<beans::PropertyValue> aGrabBag;
+            xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
+            beans::PropertyValue aPair;
+            aPair.Name = "mso-layout-flow-alt";
+            aPair.Value = uno::makeAny(maTypeModel.maLayoutFlowAlt);
+            if (aGrabBag.hasElements())
+            {
+                sal_Int32 nLength = aGrabBag.getLength();
+                aGrabBag.realloc(nLength + 1);
+                aGrabBag[nLength + 1] = aPair;
+            }
+            else
+            {
+                aGrabBag.realloc(1);
+                aGrabBag[0] = aPair;
+            }
+            xPropertySet->setPropertyValue("FrameInteropGrabBag", 
uno::makeAny(aGrabBag));
+        }
     }
     else
     {
diff --git a/oox/source/vml/vmltextboxcontext.cxx 
b/oox/source/vml/vmltextboxcontext.cxx
index 5c7e2f7..15e8810 100644
--- a/oox/source/vml/vmltextboxcontext.cxx
+++ b/oox/source/vml/vmltextboxcontext.cxx
@@ -215,6 +215,8 @@ TextBoxContext::TextBoxContext( ContextHandler2Helper& 
rParent, TextBox& rTextBo
             if( aName == "layout-flow" )      rTextBox.maLayoutFlow = aValue;
             else if (aName == "mso-fit-shape-to-text")
                 rTextBox.mrTypeModel.mbAutoHeight = true;
+            else if (aName == "mso-layout-flow-alt")
+                rTextBox.mrTypeModel.maLayoutFlowAlt = aValue;
             else
                 SAL_WARN("oox", "unhandled style property: " << aName);
         }
diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index da26031..a8ef4f2 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -227,6 +227,7 @@ RES_FRMATR_BEGIN = RES_PARATR_LIST_END,
     RES_FRMATR_CONDITIONAL_STYLE_NAME,              // 126
     RES_FILL_STYLE,                                 // 127
     RES_FILL_GRADIENT,                              // 128
+    RES_FRMATR_GRABBAG,
 RES_FRMATR_END
 };
 
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 704d595..ebc95c7 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -839,6 +839,7 @@ enum SwPropNameIds
 /* 0773 */  UNO_NAME_SHADOW_TRANSPARENCE,
 
 /* 0774 */  UNO_NAME_DOC_INTEROP_GRAB_BAG,
+/* 0775 */  UNO_NAME_FRAME_INTEROP_GRAB_BAG,
 
             SW_PROPNAME_END
 
diff --git a/sw/qa/extras/ooxmlimport/data/fdo69636.docx 
b/sw/qa/extras/ooxmlimport/data/fdo69636.docx
new file mode 100644
index 0000000..b2f3069
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/fdo69636.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index fc03f75..df6b0a1 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -135,6 +135,7 @@ public:
     void testVmlTextVerticalAdjust();
     void testGroupshapeSdt();
     void testDefaultSectBreakCols();
+    void testFdo69636();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -234,6 +235,7 @@ void Test::run()
         {"vml-text-vertical-adjust.docx", &Test::testVmlTextVerticalAdjust},
         {"groupshape-sdt.docx", &Test::testGroupshapeSdt},
         {"default-sect-break-cols.docx", &Test::testDefaultSectBreakCols},
+        {"fdo69636.docx", &Test::testFdo69636},
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1559,6 +1561,15 @@ void Test::testDefaultSectBreakCols()
     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextColumns->getColumnCount());
 }
 
+void Test::testFdo69636()
+{
+    // The problem was that the mso-layout-flow-alt:bottom-to-top VML shape 
property wasn't handled for sw text frames.
+    uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> 
xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xFrame(xIndexAccess->getByIndex(0), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(900), 
getProperty<sal_Int32>(getRun(getParagraphOfText(1, xFrame->getText()), 1), 
"CharRotation"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index 94b859a..30fc9f0 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -389,6 +389,7 @@ SfxItemInfo aSlotTab[] =
     { 0, SFX_ITEM_POOLABLE },                           // 
RES_FRMATR_CONDITIONAL_STYLE_NAME
     { SID_SW_ATTR_FILL_STYLE, SFX_ITEM_POOLABLE },                           
// RES_FILL_STYLE
     { SID_SW_ATTR_FILL_GRADIENT, SFX_ITEM_POOLABLE },                          
 // RES_FILL_GRADIENT
+    { 0, SFX_ITEM_POOLABLE },                           // RES_FRMATR_GRABBAG
 
     { 0, SFX_ITEM_POOLABLE },                           // RES_GRFATR_MIRRORGRF
     { SID_ATTR_GRAF_CROP, SFX_ITEM_POOLABLE },          // RES_GRFATR_CROPGRF
@@ -604,6 +605,7 @@ void _InitCore()
     aAttrTab[ RES_FRMATR_CONDITIONAL_STYLE_NAME - POOLATTR_BEGIN ] = new 
SfxStringItem( RES_FRMATR_CONDITIONAL_STYLE_NAME, aEmptyStr );
     aAttrTab[ RES_FILL_STYLE - POOLATTR_BEGIN ] = new 
XFillStyleItem(XFILL_SOLID, RES_FILL_STYLE);
     aAttrTab[ RES_FILL_GRADIENT - POOLATTR_BEGIN ] = new 
XFillGradientItem(RES_FILL_GRADIENT);
+    aAttrTab[ RES_FRMATR_GRABBAG - POOLATTR_BEGIN ] = new 
SfxGrabBagItem(RES_FRMATR_GRABBAG);
 
     aAttrTab[ RES_GRFATR_MIRRORGRF- POOLATTR_BEGIN ] =      new SwMirrorGrf;
     aAttrTab[ RES_GRFATR_CROPGRF- POOLATTR_BEGIN ] =        new SwCropGrf;
diff --git a/sw/source/core/unocore/unomap.cxx 
b/sw/source/core/unocore/unomap.cxx
index 6c4c3c9..1c1a135 100644
--- a/sw/source/core/unocore/unomap.cxx
+++ b/sw/source/core/unocore/unomap.cxx
@@ -302,6 +302,7 @@ SwUnoPropertyMapProvider::~SwUnoPropertyMapProvider()
     { SW_PROP_NMID(UNO_NAME_FILL_STYLE), RES_FILL_STYLE,      
CPPU_E2T(CPPUTYPE_FILLSTYLE), PROPERTY_NONE ,0}, \
     { SW_PROP_NMID(UNO_NAME_FILL_GRADIENT), RES_FILL_GRADIENT,      
CPPU_E2T(CPPUTYPE_GRADIENT), PROPERTY_NONE ,MID_FILLGRADIENT}, \
     { SW_PROP_NMID(UNO_NAME_FILL_GRADIENT_NAME), RES_FILL_GRADIENT, 
CPPU_E2T(CPPUTYPE_OUSTRING), PROPERTY_NONE ,MID_NAME}, \
+    { SW_PROP_NMID(UNO_NAME_FRAME_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, 
CPPU_E2T(CPPUTYPE_PROPERTYVALUE), PROPERTY_NONE, 0}, \
     { SW_PROP_NMID(UNO_NAME_CONTENT_PROTECTED), RES_PROTECT,            
CPPU_E2T(CPPUTYPE_BOOLEAN),             PROPERTY_NONE, MID_PROTECT_CONTENT  },  
                        \
     { SW_PROP_NMID(UNO_NAME_FRAME_STYLE_NAME), 
FN_UNO_FRAME_STYLE_NAME,CPPU_E2T(CPPUTYPE_OUSTRING),         PROPERTY_NONE, 0}, 
                                  \
     { SW_PROP_NMID(UNO_NAME_BACK_GRAPHIC_URL), RES_BACKGROUND,      
CPPU_E2T(CPPUTYPE_OUSTRING),        PROPERTY_NONE ,MID_GRAPHIC_URL    },        
         \
@@ -713,6 +714,7 @@ const SfxItemPropertyMapEntry* 
SwUnoPropertyMapProvider::GetPropertyMapEntries(s
                     { SW_PROP_NMID(UNO_NAME_FILL_STYLE), RES_FILL_STYLE,      
CPPU_E2T(CPPUTYPE_FILLSTYLE), PROPERTY_NONE ,0},
                     { SW_PROP_NMID(UNO_NAME_FILL_GRADIENT), RES_FILL_GRADIENT, 
     CPPU_E2T(CPPUTYPE_GRADIENT), PROPERTY_NONE ,MID_FILLGRADIENT},
                     { SW_PROP_NMID(UNO_NAME_FILL_GRADIENT_NAME), 
RES_FILL_GRADIENT, CPPU_E2T(CPPUTYPE_OUSTRING), PROPERTY_NONE ,MID_NAME},
+                    { SW_PROP_NMID(UNO_NAME_FRAME_INTEROP_GRAB_BAG), 
RES_FRMATR_GRABBAG, CPPU_E2T(CPPUTYPE_PROPERTYVALUE), PROPERTY_NONE, 0},
                 //  { SW_PROP_NMID(UNO_NAME_CHAIN_NEXT_NAME), RES_CHAIN,       
         CPPU_E2T(CPPUTYPE_OUSTRING),            PROPERTY_NONE 
,MID_CHAIN_NEXTNAME},
                 //  { SW_PROP_NMID(UNO_NAME_CHAIN_PREV_NAME), RES_CHAIN,       
         CPPU_E2T(CPPUTYPE_OUSTRING),            PROPERTY_NONE 
,MID_CHAIN_PREVNAME},
                 /*not impl*/    { SW_PROP_NMID(UNO_NAME_CLIENT_MAP), RES_URL,  
             CPPU_E2T(CPPUTYPE_BOOLEAN),         PROPERTY_NONE 
,MID_URL_CLIENTMAP         },
diff --git a/sw/source/core/unocore/unoprnms.cxx 
b/sw/source/core/unocore/unoprnms.cxx
index 1bdac49..2324bd5 100644
--- a/sw/source/core/unocore/unoprnms.cxx
+++ b/sw/source/core/unocore/unoprnms.cxx
@@ -806,6 +806,7 @@ const SwPropNameTab aPropNameTab = {
 /* 0772 UNO_NAME_CHAR_SHADOW_FORMAT */                 
{MAP_CHAR_LEN("CharShadowFormat")},
 /* 0773 UNO_NAME_SHADOW_TRANSPARENCE */                
{MAP_CHAR_LEN("ShadowTransparence")},
 /* 0774 UNO_NAME_DOC_INTEROP_GRAB_BAG */               
{MAP_CHAR_LEN("InteropGrabBag")},
+/* 0775 UNO_NAME_FRAME_INTEROP_GRAB_BAG */             
{MAP_CHAR_LEN("FrameInteropGrabBag")},
 
 
 // new items in this array must match enum SwPropNameIds
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 4652a40..031993f 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3649,6 +3649,9 @@ void DomainMapper::PopListProperties()
 void DomainMapper::lcl_startCharacterGroup()
 {
     m_pImpl->PushProperties(CONTEXT_CHARACTER);
+    if (m_pImpl->m_bFrameBtLr)
+        // No support for this in core, work around by char rotation, as we do 
so for table cells already.
+        m_pImpl->GetTopContext()->Insert(PROP_CHAR_ROTATION, 
uno::makeAny(sal_Int16(900)));
 }
 
 void DomainMapper::lcl_endCharacterGroup()
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 5a5ab66..b81d4ef 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -177,7 +177,8 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_pSdtHelper(0),
         m_nTableDepth(0),
         m_bHasFtnSep(false),
-        m_bIgnoreNextPara(false)
+        m_bIgnoreNextPara(false),
+        m_bFrameBtLr(false)
 
 {
     appendTableManager( );
@@ -1778,6 +1779,19 @@ void DomainMapper_Impl::PushShapeContext( const 
uno::Reference< drawing::XShape
                         uno::makeAny( true ) );
             if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
             {
+                // Extract the special "btLr text frame" mode, requested by 
oox, if needed.
+                uno::Reference<beans::XPropertySet> xPropertySet(xShape, 
uno::UNO_QUERY);
+                uno::Sequence<beans::PropertyValue> aGrabBag;
+                xPropertySet->getPropertyValue("FrameInteropGrabBag") >>= 
aGrabBag;
+                for (int i = 0; i < aGrabBag.getLength(); ++i)
+                {
+                    if (aGrabBag[i].Name == "mso-layout-flow-alt")
+                    {
+                        m_bFrameBtLr = aGrabBag[i].Value.get<OUString>() == 
"bottom-to-top";
+                        break;
+                    }
+                }
+
                 uno::Reference<text::XTextContent> xTextContent(xShape, 
uno::UNO_QUERY_THROW);
                 uno::Reference<text::XTextRange> 
xTextRange(xTextAppend->createTextCursorByRange(xTextAppend->getEnd()), 
uno::UNO_QUERY_THROW);
                 xTextAppend->insertTextContent(xTextRange, xTextContent, 
sal_False);
@@ -1858,6 +1872,7 @@ void DomainMapper_Impl::PopShapeContext()
         }
         m_aAnchoredStack.pop();
     }
+    m_bFrameBtLr = false;
 }
 
 sal_Int16 lcl_ParseNumberingType( const OUString& rCommand )
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index f61c9ad..9210184 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -709,6 +709,7 @@ public:
 
     /// If the next newline should be ignored, used by the special footnote 
separator paragraph.
     bool m_bIgnoreNextPara;
+    bool m_bFrameBtLr; ///< Bottom to top, left to right text frame direction 
is requested for the current text frame.
 };
 } //namespace dmapper
 } //namespace writerfilter
_______________________________________________
Libreoffice-commits mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to