[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