[PATCH libreoffice-4-0] implement MultiPage, Page & TabStrip import for oox

Noel Power (via Code Review) gerrit at gerrit.libreoffice.org
Thu Apr 18 06:02:29 PDT 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/3456

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/56/3456/1

implement MultiPage, Page & TabStrip import for oox

    Change-Id: I1912c9550c12a971fcc7fdbc8bd623f18ccc40b8
    (cherry picked from commit a43cc9ec8dde4f311bcf8ff96e6a26d56b2abdcf)

Change-Id: I9d31017ab149ed8a4c80feefc891dc6c911bad20
(cherry picked from commit 474362028e13f98e73ea9420834a1aaa3490fd83)
---
M oox/inc/oox/ole/axbinaryreader.hxx
M oox/inc/oox/ole/axcontrol.hxx
M oox/source/ole/axbinaryreader.cxx
M oox/source/ole/axcontrol.cxx
M oox/source/ole/vbacontrol.cxx
5 files changed, 242 insertions(+), 17 deletions(-)



diff --git a/oox/inc/oox/ole/axbinaryreader.hxx b/oox/inc/oox/ole/axbinaryreader.hxx
index d63ccb1..4a03f8a 100644
--- a/oox/inc/oox/ole/axbinaryreader.hxx
+++ b/oox/inc/oox/ole/axbinaryreader.hxx
@@ -87,7 +87,7 @@
 typedef ::std::pair< sal_Int32, sal_Int32 > AxPairData;
 
 /** An array of string values as a property. */
-typedef ::std::vector< ::rtl::OUString > AxStringArray;
+typedef ::std::vector< ::rtl::OUString > AxArrayString;
 
 // ============================================================================
 
@@ -111,7 +111,10 @@
     void                readPairProperty( AxPairData& orPairData );
     /** Reads the next string property from the stream, if the respective flag
         in the property mask is set. */
-    void                readStringProperty( ::rtl::OUString& orValue );
+    void                readStringProperty( OUString& orValue );
+    /** Reads ArrayString, an array of fmString ( compressed or uncompressed )
+        is read from the stream and inserted into rStrings */
+    void                readArrayStringProperty( std::vector< OUString >& rStrings );
     /** Reads the next GUID property from the stream, if the respective flag
         in the property mask is set. The GUID will be enclosed in braces. */
     void                readGuidProperty( ::rtl::OUString& orGuid );
@@ -135,6 +138,9 @@
     /** Skips the next string property in the stream, if the respective flag in
         the property mask is set. */
     inline void         skipStringProperty() { readStringProperty( maDummyString ); }
+    /** Skips the next ArrayString property in the stream, if the respective flag in
+        the property mask is set. */
+    inline void         skipArrayStringProperty() { readArrayStringProperty( maDummyArrayString ); }
     /** Skips the next GUID property in the stream, if the respective flag in
         the property mask is set. */
     inline void         skipGuidProperty() { readGuidProperty( maDummyString ); }
@@ -185,11 +191,11 @@
     };
 
     /** Complex property for an array of strings. */
-    struct StringArrayProperty : public ComplexProperty
+    struct ArrayStringProperty : public ComplexProperty
     {
-        AxStringArray&      mrArray;
+        AxArrayString&      mrArray;
         sal_uInt32          mnSize;
-        inline explicit     StringArrayProperty( AxStringArray& rArray, sal_uInt32 nSize ) :
+        inline explicit     ArrayStringProperty( AxArrayString& rArray, sal_uInt32 nSize ) :
                                 mrArray( rArray ), mnSize( nSize ) {}
         virtual bool        readProperty( AxAlignedInputStream& rInStrm );
     };
@@ -233,8 +239,8 @@
     AxPairData          maDummyPairData;    ///< Dummy pair for unsupported properties.
     AxFontData          maDummyFontData;    ///< Dummy font for unsupported properties.
     StreamDataSequence  maDummyPicData;     ///< Dummy picture for unsupported properties.
-    ::rtl::OUString     maDummyString;      ///< Dummy string for unsupported properties.
-    AxStringArray       maDummyStringArray; ///< Dummy string array for unsupported properties.
+    OUString     maDummyString;      ///< Dummy string for unsupported properties.
+    AxArrayString maDummyArrayString; ///< Dummy strings for unsupported ArrayString properties.
     sal_Int64           mnPropFlags;        ///< Flags specifying existing properties.
     sal_Int64           mnNextProp;         ///< Next property to read.
     sal_Int64           mnPropsEnd;         ///< End position of simple/large properties.
diff --git a/oox/inc/oox/ole/axcontrol.hxx b/oox/inc/oox/ole/axcontrol.hxx
index 9e00278..1f4b640 100644
--- a/oox/inc/oox/ole/axcontrol.hxx
+++ b/oox/inc/oox/ole/axcontrol.hxx
@@ -157,13 +157,13 @@
     API_CONTROL_COMBOBOX,
     API_CONTROL_SPINBUTTON,
     API_CONTROL_SCROLLBAR,
-    API_CONTROL_TABSTRIP,
+    API_CONTROL_TABSTRIP, //11
     API_CONTROL_PROGRESSBAR,
     API_CONTROL_GROUPBOX,
-    API_CONTROL_FRAME,
-    API_CONTROL_PAGE,
-    API_CONTROL_MULTIPAGE,
-    API_CONTROL_DIALOG
+    API_CONTROL_FRAME, // 14
+    API_CONTROL_PAGE,  // 15
+    API_CONTROL_MULTIPAGE, // 16
+    API_CONTROL_DIALOG // 17
 };
 
 // ============================================================================
@@ -601,6 +601,24 @@
     bool                mbPicTiling;        ///< True = picture is repeated.
 };
 
+class OOX_DLLPUBLIC AxTabStripModel : public AxFontDataModel
+{
+public:
+    explicit            AxTabStripModel();
+
+    virtual bool        importBinaryModel( BinaryInputStream& rInStrm );
+
+    virtual ApiControlType getControlType() const;
+
+public:
+    sal_uInt32   mnListIndex;
+    sal_uInt32   mnTabStyle;
+    sal_uInt32   mnTabData;
+    sal_uInt32   mnVariousPropertyBits;
+    std::vector< ::rtl::OUString > maItems; // captions for each tab
+    std::vector< ::rtl::OUString > maTabNames; // names for each tab
+};
+
 // ============================================================================
 
 /** Base class for a Forms 2.0 morph data control. */
@@ -854,6 +872,28 @@
     virtual void        convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
 };
 
+class OOX_DLLPUBLIC AxPageModel : public AxContainerModelBase
+{
+public:
+    explicit            AxPageModel();
+
+    virtual ApiControlType getControlType() const;
+    virtual void        convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+};
+
+class OOX_DLLPUBLIC AxMultiPageModel : public AxContainerModelBase
+{
+public:
+    explicit            AxMultiPageModel();
+
+    virtual ApiControlType getControlType() const;
+    virtual bool        importPageAndMultiPageProperties( BinaryInputStream& rInStrm, sal_Int32 nPages );
+    virtual void        convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const;
+    std::vector<sal_uInt32> mnIDs;
+    sal_uInt32          mnActiveTab;
+    sal_uInt32          mnTabStyle;
+};
+
 // ============================================================================
 
 
diff --git a/oox/source/ole/axbinaryreader.cxx b/oox/source/ole/axbinaryreader.cxx
index 9b660c0..347baee 100644
--- a/oox/source/ole/axbinaryreader.cxx
+++ b/oox/source/ole/axbinaryreader.cxx
@@ -148,7 +148,7 @@
     return lclReadString( rInStrm, mrValue, mnSize, false );
 }
 
-bool AxBinaryPropertyReader::StringArrayProperty::readProperty( AxAlignedInputStream& rInStrm )
+bool AxBinaryPropertyReader::ArrayStringProperty::readProperty( AxAlignedInputStream& rInStrm )
 {
     sal_Int64 nEndPos = rInStrm.tell() + mnSize;
     while( rInStrm.tell() < nEndPos )
@@ -224,6 +224,15 @@
         maLargeProps.push_back( ComplexPropVector::value_type( new GuidProperty( orGuid ) ) );
 }
 
+void AxBinaryPropertyReader::readArrayStringProperty( std::vector<OUString>& orValue )
+{
+    if( startNextProperty() )
+    {
+        sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >();
+        maLargeProps.push_back( ComplexPropVector::value_type( new ArrayStringProperty( orValue, nSize ) ) );
+    }
+}
+
 void AxBinaryPropertyReader::readFontProperty( AxFontData& orFontData )
 {
     if( startNextProperty() )
diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx
index e056fde..04373b2 100644
--- a/oox/source/ole/axcontrol.cxx
+++ b/oox/source/ole/axcontrol.cxx
@@ -1352,6 +1352,53 @@
 
 // ============================================================================
 
+AxTabStripModel::AxTabStripModel() :
+    mnListIndex( 0 ),
+    mnTabStyle( 0 ),
+    mnTabData( 0 ),
+    mnVariousPropertyBits( 0 )
+{
+}
+
+bool AxTabStripModel::importBinaryModel( BinaryInputStream& rInStrm )
+{
+    // not worth reading much here, basically we are interested
+    // in whether we have tabs, the width, the height and the
+    // captions, everything else we can pretty much discard ( for now )
+    AxBinaryPropertyReader aReader( rInStrm );
+    aReader.readIntProperty< sal_uInt32 >( mnListIndex ); // ListIndex
+    aReader.skipIntProperty< sal_uInt32 >(); // Backcolor
+    aReader.skipIntProperty< sal_uInt32 >(); // ForeColor
+    aReader.skipUndefinedProperty();
+    aReader.readPairProperty( maSize );
+    aReader.readArrayStringProperty( maItems );
+    aReader.skipIntProperty< sal_uInt8 >();  // MousePointer
+    aReader.skipUndefinedProperty();
+    aReader.skipIntProperty< sal_uInt32 >(); // TabOrientation
+    aReader.readIntProperty< sal_uInt32 >(mnTabStyle); // TabStyle
+    aReader.skipBoolProperty();              // MultiRow
+    aReader.skipIntProperty< sal_uInt32 >(); // TabFixedWidth
+    aReader.skipIntProperty< sal_uInt32 >(); // TabFixedHeight
+    aReader.skipBoolProperty();              // ToolTips
+    aReader.skipUndefinedProperty();
+    aReader.skipArrayStringProperty();  // ToolTip strings
+    aReader.skipUndefinedProperty();
+    aReader.readArrayStringProperty( maTabNames ); // Tab names
+    aReader.readIntProperty< sal_uInt32 >(mnVariousPropertyBits); // VariousPropertyBits
+    aReader.skipBoolProperty();// NewVersion
+    aReader.skipIntProperty< sal_uInt32 >(); // TabsAllocated
+    aReader.skipArrayStringProperty();  // Tags
+    aReader.readIntProperty<sal_uInt32 >(mnTabData);  // TabData
+    aReader.skipArrayStringProperty();  // Accelerators
+    aReader.skipPictureProperty(); // Mouse Icon
+    return aReader.finalizeImport() && AxFontDataModel::importBinaryModel( rInStrm );
+}
+
+ApiControlType AxTabStripModel::getControlType() const
+{
+    return API_CONTROL_TABSTRIP;
+}
+
 AxMorphDataModelBase::AxMorphDataModelBase() :
     mnTextColor( AX_SYSCOLOR_WINDOWTEXT ),
     mnBackColor( AX_SYSCOLOR_WINDOWBACK ),
@@ -2386,6 +2433,74 @@
     AxContainerModelBase::convertProperties( rPropMap, rConv );
 }
 
+AxPageModel::AxPageModel()
+{
+}
+
+ApiControlType AxPageModel::getControlType() const
+{
+    return API_CONTROL_PAGE;
+}
+
+void AxPageModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+    rPropMap.setProperty( PROP_Title, maCaption );
+    rConv.convertColor( rPropMap, PROP_BackgroundColor, mnBackColor );
+    rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_CONTAINER_ENABLED ) );
+    AxContainerModelBase::convertProperties( rPropMap, rConv );
+}
+
+AxMultiPageModel::AxMultiPageModel() :
+    mnActiveTab( 0 ),
+    mnTabStyle( AX_TABSTRIP_TABS )
+{
+}
+
+ApiControlType AxMultiPageModel::getControlType() const
+{
+    return API_CONTROL_MULTIPAGE;
+}
+
+
+bool AxMultiPageModel::importPageAndMultiPageProperties( BinaryInputStream& rInStrm, sal_Int32 nPages )
+{
+    // PageProperties
+    for ( sal_Int32 nPage = 0; nPage < nPages; ++nPage )
+    {
+        AxBinaryPropertyReader aReader( rInStrm );
+        aReader.skipUndefinedProperty();
+        aReader.skipIntProperty< sal_uInt32 >(); // TransistionEffect
+        aReader.skipIntProperty< sal_uInt32 >(); // TransitionPeriod
+    }
+    // MultiPageProperties
+    AxBinaryPropertyReader aReader( rInStrm );
+    sal_uInt32 nPageCount = 0;
+    aReader.skipUndefinedProperty();
+    aReader.readIntProperty< sal_uInt32 >(nPageCount); // PageCount
+    aReader.skipIntProperty< sal_uInt32 >(); //ID
+
+    // IDs
+    for ( sal_uInt32 count = 0; count < nPageCount; ++count )
+    {
+        sal_Int32 nID = 0;
+        rInStrm >> nID;
+        mnIDs.push_back( nID );
+    }
+    return true;
+}
+
+void AxMultiPageModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
+{
+    rPropMap.setProperty( PROP_Title, maCaption );
+    rPropMap.setProperty( PROP_MultiPageValue, mnActiveTab + 1);
+    rConv.convertColor( rPropMap, PROP_BackgroundColor, mnBackColor );
+    rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_CONTAINER_ENABLED ) );
+    rPropMap.setProperty( PROP_Decoration, mnTabStyle != AX_TABSTRIP_NONE );
+
+    AxContainerModelBase::convertProperties( rPropMap, rConv );
+}
+
+
 // ============================================================================
 
 AxUserFormModel::AxUserFormModel()
diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx
index 607b8e6..91b0ac6 100644
--- a/oox/source/ole/vbacontrol.cxx
+++ b/oox/source/ole/vbacontrol.cxx
@@ -36,6 +36,7 @@
 #include "oox/helper/storagebase.hxx"
 #include "oox/helper/textinputstream.hxx"
 #include "oox/ole/vbahelper.hxx"
+#include <boost/unordered_map.hpp>
 
 namespace oox {
 namespace ole {
@@ -259,10 +260,13 @@
             case VBA_SITE_COMBOBOX:         xCtrlModel.reset( new AxComboBoxModel );        break;
             case VBA_SITE_SPINBUTTON:       xCtrlModel.reset( new AxSpinButtonModel );      break;
             case VBA_SITE_SCROLLBAR:        xCtrlModel.reset( new AxScrollBarModel );       break;
-            case VBA_SITE_TABSTRIP:                                                         break;
+            case VBA_SITE_TABSTRIP:         xCtrlModel.reset( new AxTabStripModel );
+            break;
             case VBA_SITE_FRAME:            xCtrlModel.reset( new AxFrameModel );           break;
-            case VBA_SITE_MULTIPAGE:                                                        break;
-            case VBA_SITE_FORM:                                                             break;
+            case VBA_SITE_MULTIPAGE:        xCtrlModel.reset( new AxMultiPageModel );
+            break;
+            case VBA_SITE_FORM:             xCtrlModel.reset( new AxPageModel );
+            break;
             default:    OSL_FAIL( "VbaSiteModel::createControlModel - unknown type index" );
         }
     }
@@ -405,7 +409,6 @@
                 maControls vector). Ignore failure of importSiteModels() but
                 try to import as much controls as possible. */
             importEmbeddedSiteModels( aFStrm );
-
             /*  Open the 'o' stream containing models of embedded simple
                 controls. Stream may be empty or missing, if this control
                 contains no controls or only container controls. */
@@ -417,6 +420,58 @@
             maControls.forEachMem( &VbaFormControl::importModelOrStorage,
                 ::boost::ref( aOStrm ), ::boost::ref( rStrg ), ::boost::cref( maClassTable ) );
 
+            // Special handling for multi-page which has non-standard
+            // containment and additionally needs to re-order Page children
+            if ( pContainerModel->getControlType() == API_CONTROL_MULTIPAGE )
+            {
+                AxMultiPageModel* pMultiPage = dynamic_cast< AxMultiPageModel* >( pContainerModel );
+                if ( pMultiPage )
+                {
+                    BinaryXInputStream aXStrm( rStrg.openInputStream( "x" ), true );
+                    pMultiPage->importPageAndMultiPageProperties( aXStrm, maControls.size() );
+                }
+                typedef boost::unordered_map< sal_uInt32, ::boost::shared_ptr< VbaFormControl > > IdToPageMap;
+                IdToPageMap idToPage;
+                VbaFormControlVector::iterator it = maControls.begin();
+                VbaFormControlVector::iterator it_end = maControls.end();
+                typedef std::vector< sal_uInt32 > UInt32Array;
+                AxArrayString sCaptions;
+
+                for ( ; it != it_end; ++it )
+                {
+                    if ( (*it)->mxCtrlModel->getControlType() == API_CONTROL_PAGE )
+                    {
+                        VbaSiteModelRef xPageSiteRef = (*it)->mxSiteModel;
+                        if ( xPageSiteRef.get() )
+                            idToPage[ xPageSiteRef->getId() ] = (*it);
+                    }
+                    else
+                    {
+                        AxTabStripModel* pTabStrip = static_cast<AxTabStripModel*> ( (*it)->mxCtrlModel.get() );
+                        sCaptions = pTabStrip->maItems;
+                        pMultiPage->mnActiveTab = pTabStrip->mnListIndex;
+                        pMultiPage->mnTabStyle = pTabStrip->mnTabStyle;
+                    }
+                }
+                // apply caption/titles to pages
+                UInt32Array::iterator itCtrlId = pMultiPage->mnIDs.begin();
+                UInt32Array::iterator itCtrlId_end = pMultiPage->mnIDs.end();
+                AxArrayString::iterator itCaption = sCaptions.begin();
+
+                maControls.clear();
+                // need to sort the controls according to the order of the ids
+                for ( sal_Int32 index = 1 ; ( sCaptions.size() == idToPage.size() ) && itCtrlId != itCtrlId_end; ++itCtrlId, ++itCaption, ++index )
+                {
+                    IdToPageMap::iterator iter = idToPage.find( *itCtrlId );
+                    if ( iter != idToPage.end() )
+                    {
+                        AxPageModel* pPage = static_cast<AxPageModel*> ( iter->second->mxCtrlModel.get() );
+
+                        pPage->importProperty( XML_Caption, *itCaption );
+                        maControls.push_back( iter->second );
+                    }
+                }
+            }
             /*  Reorder the controls (sorts all option buttons of an option
                 group together), and move all children of all embedded frames
                 (group boxes) to this control (UNO group boxes cannot contain

-- 
To view, visit https://gerrit.libreoffice.org/3456
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9d31017ab149ed8a4c80feefc891dc6c911bad20
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: Noel Power <noel.power at suse.com>



More information about the LibreOffice mailing list