[Libreoffice-commits] .: 3 commits - filter/inc filter/source oox/inc oox/source

Noel Power noelp at kemper.freedesktop.org
Wed Oct 13 07:22:41 PDT 2010


 filter/inc/filter/msfilter/escherex.hxx  |   21 
 filter/inc/filter/msfilter/msocximex.hxx |   84 --
 filter/inc/filter/msfilter/mstoolbar.hxx |  334 ++++++++++
 filter/inc/filter/msfilter/svxmsbas.hxx  |   18 
 filter/source/msfilter/eschesdo.cxx      |   13 
 filter/source/msfilter/makefile.mk       |    2 
 filter/source/msfilter/msocximex.cxx     |  981 ++++++++++++++++++-------------
 filter/source/msfilter/msoleexp.cxx      |    5 
 filter/source/msfilter/mstoolbar.cxx     |  817 +++++++++++++++++++++++++
 filter/source/msfilter/msvbasic.cxx      |  812 +++++++++++++++++++++++++
 filter/source/msfilter/msvbasic.hxx      |   11 
 filter/source/msfilter/svxmsbas.cxx      |  119 +++
 oox/inc/oox/ole/vbacontrol.hxx           |    2 
 oox/source/ole/vbacontrol.cxx            |    5 
 oox/source/ole/vbaproject.cxx            |    2 
 15 files changed, 2747 insertions(+), 479 deletions(-)

New commits:
commit 9137cfe7b70f6ef84bf4f751c7e32b66d29e4663
Merge: bbbdc9b... 6619f52...
Author: Noel Power <noel.power at novell.com>
Date:   Wed Oct 13 15:16:48 2010 +0100

    Merge branch 'master' of ssh://noelp@git.freedesktop.org/git/libreoffice/filters

commit bbbdc9bff05808cb5e7bf7ef9a729060da78c73c
Author: Noel Power <noel.power at novell.com>
Date:   Wed Oct 6 10:32:11 2010 +0100

    initial commit for vba blob ( not including container_control stuff )

diff --git a/filter/inc/filter/msfilter/mstoolbar.hxx b/filter/inc/filter/msfilter/mstoolbar.hxx
new file mode 100644
index 0000000..c117645
--- /dev/null
+++ b/filter/inc/filter/msfilter/mstoolbar.hxx
@@ -0,0 +1,334 @@
+#ifndef _MSTOOLBAR_HXX
+#define _MSTOOLBAR_HXX
+#include "filter/msfilter/msfilterdllapi.h"
+#include <tools/string.hxx>
+#include <sot/storage.hxx>
+#include <ostream>
+#include <memory>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <vcl/bitmap.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+namespace css = ::com::sun::star;
+
+class TBCHeader;
+
+
+class MSOCommandConvertor
+{
+public:
+    virtual ~MSOCommandConvertor() {}
+    virtual rtl::OUString MSOCommandToOOCommand( sal_Int16 msoCmd ) = 0; 
+    virtual rtl::OUString MSOTCIDToOOCommand( sal_Int16 msoTCID ) = 0; 
+};
+
+class SfxObjectShell;
+
+class MSFILTER_DLLPUBLIC CustomToolBarImportHelper
+{
+    struct iconcontrolitem
+    {
+        rtl::OUString sCommand;
+        css::uno::Reference< css::graphic::XGraphic > image;
+    };
+    std::vector< iconcontrolitem > iconcommands;
+    std::auto_ptr< MSOCommandConvertor > pMSOCmdConvertor;
+    css::uno::Reference< css::ui::XUIConfigurationManagerSupplier > m_xCfgSupp;
+    css::uno::Reference< css::ui::XUIConfigurationManager > m_xAppCfgMgr;
+    SfxObjectShell& mrDocSh;
+    void ScaleImage( css::uno::Reference< css::graphic::XGraphic >& xGraphic, long nNewSize );
+public:
+    CustomToolBarImportHelper( SfxObjectShell& rDocSh, const css::uno::Reference< css::ui::XUIConfigurationManager >& rxAppCfgMgr );
+
+    void setMSOCommandMap( MSOCommandConvertor* pCnvtr ) { pMSOCmdConvertor.reset( pCnvtr ); }
+    css::uno::Reference< css::ui::XUIConfigurationManager > getCfgManager();
+    css::uno::Reference< css::ui::XUIConfigurationManager > getAppCfgManager();
+
+
+    css::uno::Any createCommandFromMacro( const rtl::OUString& sCmd );
+
+    void addIcon( const css::uno::Reference< css::graphic::XGraphic >& xImage, const rtl::OUString& sString );
+    void applyIcons();
+    rtl::OUString MSOCommandToOOCommand( sal_Int16 msoCmd );
+    rtl::OUString MSOTCIDToOOCommand( sal_Int16 msoTCID );
+    SfxObjectShell& GetDocShell() { return mrDocSh; }
+    void showToolbar( const rtl::OUString& rName );
+    bool createMenu( const rtl::OUString& rName, const css::uno::Reference< css::container::XIndexAccess >& xMenuDesc, bool bPersist );
+};
+
+class MSFILTER_DLLPUBLIC TBBase
+{
+friend class Indent;
+    static int nIndent; // num spaces to indent before printing 
+protected:
+    void indent_printf(FILE* fp, const char* format, ... );
+    sal_uInt32 nOffSet; // usually for debug we can store the offset in the stream to this record
+public:
+    TBBase() : nOffSet( 0 ) {}
+    virtual ~TBBase(){}
+    rtl::OUString readUnicodeString( SvStream* pS, sal_Int32 nChars );
+
+    virtual bool Read(SvStream *pS) = 0;
+    virtual void Print( FILE* ) {} // #FIXME remove this an implement the debug routines in all the classes below to enable some sort of readable output
+    sal_uInt32 GetOffset() { return nOffSet; }
+};
+
+class Indent
+{
+public:
+    Indent( bool binit = false ) 
+    { 
+        if ( binit )
+            init();
+        else
+            TBBase::nIndent = TBBase::nIndent + 2; 
+    }
+    ~Indent() { TBBase::nIndent = TBBase::nIndent - 2; }
+    void init() { TBBase::nIndent = 0; }
+};
+
+
+class MSFILTER_DLLPUBLIC WString : public TBBase
+{
+    rtl::OUString sString;
+
+public:
+    WString(){};
+    ~WString(){};
+    bool Read(SvStream *pS);
+    rtl::OUString getString(){ return sString; }
+};
+
+class MSFILTER_DLLPUBLIC TBCExtraInfo : public TBBase
+{
+    WString wstrHelpFile;
+    sal_Int32 idHelpContext;
+    WString wstrTag;
+    WString wstrOnAction;
+    WString wstrParam;
+    sal_Int8 tbcu;
+    sal_Int8 tbmg;
+
+    TBCExtraInfo(const TBCExtraInfo&);
+    TBCExtraInfo& operator = ( const TBCExtraInfo&);
+public:
+    TBCExtraInfo();
+    ~TBCExtraInfo(){}
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+    rtl::OUString getOnAction();
+};
+
+class MSFILTER_DLLPUBLIC TBCGeneralInfo  : public TBBase
+{
+    sal_uInt8 bFlags;
+    WString customText;
+    WString descriptionText;
+    WString tooltip;
+    TBCExtraInfo extraInfo;
+
+public:
+    TBCGeneralInfo();
+    ~TBCGeneralInfo() {}
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+    bool ImportToolBarControlData( CustomToolBarImportHelper&, std::vector< css::beans::PropertyValue >& );
+    rtl::OUString CustomText() { return customText.getString(); }
+    rtl::OUString DescriptionText() { return descriptionText.getString(); }
+    rtl::OUString Tooltip() { return tooltip.getString(); }
+};
+
+class MSFILTER_DLLPUBLIC TBCBitMap : public TBBase
+{
+friend class TBCBSpecific; // #FIXME hacky access, need to fix
+    sal_Int32 cbDIB;
+    Bitmap mBitMap;
+    int size;
+public:
+    TBCBitMap();
+    ~TBCBitMap();
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+    Bitmap& getBitMap(); 
+};
+
+class MSFILTER_DLLPUBLIC TBCMenuSpecific : public TBBase
+{
+    sal_Int32 tbid;
+    boost::shared_ptr< WString > name; //exist only if tbid equals 0x00000001
+public:
+    TBCMenuSpecific();
+    ~TBCMenuSpecific(){}
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+    rtl::OUString Name();
+};
+
+class MSFILTER_DLLPUBLIC TBCCDData : public TBBase
+{
+    sal_Int16 cwstrItems; //Signed integer that specifies the number of items in wstrList. MUST be positive.
+    std::vector< WString > wstrList;  // Zero-based index array of WString structures. Number of elements MUST be equal to cwstrItems.
+    sal_Int16 cwstrMRU; // Signed integer that specifies the number of most recently used string
+    sal_Int16 iSel ; // Signed integer that specifies the zero-based index of the selected item in the wstrList field. MUST be equal to 0xFFFF (-1) or greater than or equal to 0x0000.
+    sal_Int16 cLines; // Signed integer that specifies the suggested number of lines that the toolbar control will display at any time when displaying the elements of wstrList of available items. 
+    sal_Int16 dxWidth; // Signed integer that specifies the width in pixels that the interior of the dropdown has. This excludes the width of the toolbar control border and scroll bar.
+    WString wstrEdit; //Structure of type WString. Editable text for editable area of the ComboBox toolbar control.
+
+public:
+    TBCCDData();
+    ~TBCCDData();
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+};
+
+class TBCComboDropdownSpecific : public TBBase
+{
+    boost::shared_ptr< TBCCDData > data;
+public:
+    TBCComboDropdownSpecific( const TBCHeader& header );
+    TBCComboDropdownSpecific(){}
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+};
+
+class TBCBSpecific :  public TBBase
+{
+    sal_uInt8 bFlags;
+    boost::shared_ptr< TBCBitMap > icon; // optional
+    boost::shared_ptr< TBCBitMap > iconMask; // optional
+    boost::shared_ptr< sal_uInt16 > iBtnFace; // optional
+    boost::shared_ptr< WString > wstrAcc; // optional
+   
+public:
+    TBCBSpecific();
+    ~TBCBSpecific(){}
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+    // #TODO just add a getGraphic member here
+    TBCBitMap* getIcon();
+    TBCBitMap* getIconMask();
+    sal_uInt16* getBtnFace() { return iBtnFace.get(); }
+};
+
+/* TBCHeader.tct                   controlSpecificInfo type
+
+0x01 (Button control)              TBCBSpecific
+0x10 (ExpandingGrid control)       TBCBSpecific
+0x0A (Popup control)               TBCMenuSpecific
+0x0C (ButtonPopup control)         TBCMenuSpecific
+0x0D (SplitButtonPopup control)    TBCMenuSpecific
+0x0E (SplitButtonMRUPopup control) TBCMenuSpecific
+0x02 (Edit control)                TBCComboDropdow nSpecific
+0x04 (ComboBox control)            TBCComboDropdow nSpecific
+0x14 (GraphicCombo control)        TBCComboDropdow nSpecific
+0x03 (DropDown control)            TBCComboDropdow nSpecific
+0x06 (SplitDropDown control)       TBCComboDropdow nSpecific
+0x09 (GraphicDropDown control)     TBCComboDropdow nSpecific
+0x07 (OCXDropDown control)         controlSpecificInfo MUST NOT exist
+0x0F (Label control)               controlSpecificInfo MUST NOT exist
+0x12 (Grid control)                controlSpecificInfo MUST NOT exist
+0x13 (Gauge control)               controlSpecificInfo MUST NOT exist
+0x16 (ActiveX control)             controlSpecificInfo MUST NOT exist
+
+*/
+class MSFILTER_DLLPUBLIC TBCHeader : public TBBase
+{
+    sal_Int8 bSignature; 
+    sal_Int8 bVersion; 
+    sal_uInt8 bFlagsTCR; 
+    sal_uInt8 tct; 
+    sal_uInt16 tcid;
+    sal_uInt32 tbct;
+    sal_uInt8 bPriority;
+    boost::shared_ptr< sal_uInt16 > width;  //optional
+    boost::shared_ptr< sal_uInt16 > height; //optional
+
+public:
+    TBCHeader();
+    ~TBCHeader();
+    sal_uInt8 getTct() const { return tct; }
+    sal_uInt16 getTcID() const { return tcid; }
+    bool isVisible() { return !( bFlagsTCR & 0x1 ); }
+    bool isBeginGroup() { return ( bFlagsTCR & 0x2 ); }
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+    sal_uInt32 getTbct() { return tbct; };
+};
+
+class MSFILTER_DLLPUBLIC TBCData : public TBBase
+{
+    TBCHeader rHeader;
+    TBCGeneralInfo controlGeneralInfo;
+    boost::shared_ptr< TBBase > controlSpecificInfo; // can be one of TBCBSpecific, TBCMenuSpecific or TBCComboDropdow nSpecific depending on the control type specified by TBCHeader.tct 
+    TBCData(const TBCData&);
+    TBCData& operator = ( const TBCData&);
+public:
+    TBCData( const TBCHeader& Header );
+    ~TBCData(){}
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+    bool ImportToolBarControl( CustomToolBarImportHelper&, std::vector< css::beans::PropertyValue >&, bool& bBeginGroup, bool bIsMenuBar );
+    TBCGeneralInfo& getGeneralInfo() { return controlGeneralInfo; }
+    TBCMenuSpecific* getMenuSpecific();
+};
+
+class MSFILTER_DLLPUBLIC TB : public TBBase
+{
+    sal_uInt8 bSignature;// Signed integer that specifies the toolbar signature number. MUST be 0x02.
+    sal_uInt8 bVersion; // Signed integer that specifies the toolbar version number. MUST be 0x01.
+    sal_Int16 cCL; // Signed integer that SHOULD  specify the number of toolbar controls contained in this toolbar.
+    sal_Int32 ltbid;// Signed integer that specifies the toolbar ID. MUST be 0x0001 (custom toolbar ID).
+    sal_uInt32 ltbtr;// Unsigned integer of type TBTRFlags that specifies the toolbar type and toolbar restrictions.
+    sal_uInt16 cRowsDefault;// Unsigned integer that specifies the number of preferred rows for the toolbar when the toolbar is not docked. MUST be less than or equal to 255.
+    sal_uInt16 bFlags; //Unsigned integer of type TBFlags.
+    WString name; //Structure of type WString that specifies the toolbar name
+public:
+    TB();
+    ~TB(){}
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+    sal_Int16 getcCL(){ return cCL; }
+    WString& getName(){ return name; }
+    bool IsEnabled();
+    bool IsMenuToolbar(){ return ( ( ltbtr & 0x2000000 ) == 0x2000000 ); }
+    bool NeedsPositioning();
+};
+
+class MSFILTER_DLLPUBLIC SRECT : public TBBase
+{
+public:
+    SRECT() : left(0), top(0), right(0), bottom(0) {}
+    sal_Int16 left;
+    sal_Int16 top;
+    sal_Int16 right;
+    sal_Int16 bottom;
+    bool Read( SvStream* pS ) { *pS >> left >> top >> right >> bottom; return true; }
+    void Print( FILE* fo );
+};
+
+typedef cppu::WeakImplHelper1< css::container::XIndexContainer > PropertyValueIndexContainer_BASE;
+
+class MSFILTER_DLLPUBLIC TBVisualData : public TBBase
+{
+    sal_Int8 tbds;
+    sal_Int8 tbv;
+    sal_Int8 tbdsDock;
+    sal_Int8 iRow;
+
+    SRECT rcDock;
+    SRECT rcFloat;
+
+public:
+    TBVisualData();
+    ~TBVisualData(){}
+    bool Read(SvStream *pS);
+    void Print( FILE* );
+};
+#endif
diff --git a/filter/source/msfilter/mstoolbar.cxx b/filter/source/msfilter/mstoolbar.cxx
new file mode 100644
index 0000000..eead43c
--- /dev/null
+++ b/filter/source/msfilter/mstoolbar.cxx
@@ -0,0 +1,817 @@
+#include <filter/msfilter/mstoolbar.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <stdarg.h>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/ui/XImageManager.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/ui/ItemStyle.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <fstream>
+#include <vcl/graph.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/image.hxx>
+#include <map>
+#include <sfx2/objsh.hxx>
+#include <basic/basmgr.hxx>
+#include <svtools/filterutils.hxx>
+#include <boost/scoped_array.hpp>
+#include <filter/msfilter/msvbahelper.hxx>
+#include <svtools/miscopt.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+
+using namespace com::sun::star;
+
+int TBBase::nIndent = 0;
+
+void CustomToolBarImportHelper::showToolbar( const rtl::OUString& rName )
+{
+    try
+    {
+        uno::Reference< frame::XController > xCntrller( mrDocSh.GetModel()->getCurrentController(), uno::UNO_QUERY_THROW );
+        uno::Reference< beans::XPropertySet > xProps( xCntrller->getFrame(), uno::UNO_QUERY_THROW );
+        uno::Reference< frame::XLayoutManager > xLayoutMgr( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("LayoutManager") ) ), uno::UNO_QUERY_THROW );
+        xLayoutMgr->showElement( rName );
+    }
+    catch( uno::Exception& ) {}
+}
+
+void CustomToolBarImportHelper::ScaleImage( uno::Reference< graphic::XGraphic >& xGraphic, long nNewSize )
+{
+    Graphic aGraphic( xGraphic );
+    Size aSize = aGraphic.GetSizePixel();
+    if ( aSize.Height() && ( aSize.Height() == aSize.Width() ) )
+    {
+        Image aImage( xGraphic );
+        if ( aSize.Height() != nNewSize )
+        {
+            BitmapEx aBitmap = aImage.GetBitmapEx();
+            BitmapEx aBitmapex = BitmapEx::AutoScaleBitmap(aBitmap, nNewSize );
+            aImage = Image( aBitmapex);
+            xGraphic = aImage.GetXGraphic();
+        }
+    } 
+}
+
+void CustomToolBarImportHelper::applyIcons()
+{
+    for ( std::vector< iconcontrolitem >::iterator it = iconcommands.begin(); it != iconcommands.end(); ++it )
+    {
+        uno::Sequence< rtl::OUString > commands(1);
+        commands[ 0 ] = it->sCommand;
+        uno::Sequence< uno::Reference< graphic::XGraphic > > images(1);
+        images[ 0 ] = it->image;
+       
+        OSL_TRACE("About to applyIcons for command %s, have image ? %s", rtl::OUStringToOString( commands[ 0 ], RTL_TEXTENCODING_UTF8 ).getStr(), images[ 0 ].is() ? "yes" : "no" );
+        uno::Reference< ui::XImageManager > xImageManager( getCfgManager()->getImageManager(), uno::UNO_QUERY_THROW );
+        sal_uInt16 nColor = ui::ImageType::COLOR_NORMAL; 
+
+        Window* topwin = Application::GetActiveTopWindow();
+	if ( topwin != NULL && topwin->GetDisplayBackground().GetColor().IsDark() )
+            nColor = css::ui::ImageType::COLOR_HIGHCONTRAST;
+
+        ScaleImage( images[ 0 ], 16 );
+        xImageManager->replaceImages( ui::ImageType::SIZE_DEFAULT | nColor,  commands, images );
+        ScaleImage( images[ 0 ], 26 );
+        xImageManager->replaceImages( ui::ImageType::SIZE_LARGE | nColor,  commands, images );
+    }
+}
+
+void CustomToolBarImportHelper::addIcon( const uno::Reference< graphic::XGraphic >& xImage, const rtl::OUString& sString )
+{
+    iconcontrolitem item;
+    item.sCommand = sString;
+    item.image = xImage;
+    iconcommands.push_back( item );
+}
+
+CustomToolBarImportHelper::CustomToolBarImportHelper( SfxObjectShell& rDocShell,  const css::uno::Reference< css::ui::XUIConfigurationManager>& rxAppCfgMgr ) : mrDocSh( rDocShell ) 
+{
+    m_xCfgSupp.set( mrDocSh.GetModel(), uno::UNO_QUERY_THROW );
+    m_xAppCfgMgr.set( rxAppCfgMgr, uno::UNO_QUERY_THROW );
+}
+
+uno::Reference< ui::XUIConfigurationManager > 
+CustomToolBarImportHelper::getCfgManager()
+{
+    return m_xCfgSupp->getUIConfigurationManager();
+}
+
+uno::Reference< ui::XUIConfigurationManager > 
+CustomToolBarImportHelper::getAppCfgManager()
+{
+    return m_xAppCfgMgr;
+}
+
+uno::Any 
+CustomToolBarImportHelper::createCommandFromMacro( const rtl::OUString& sCmd )
+{
+//"vnd.sun.star.script:Standard.Module1.Main?language=Basic&location=document"    
+    static rtl::OUString scheme = rtl::OUString::createFromAscii( "vnd.sun.star.script:");
+    static rtl::OUString part2 = rtl::OUString::createFromAscii("?language=Basic&location=document");
+    // create script url
+    rtl::OUString scriptURL = scheme + sCmd + part2;
+    return uno::makeAny( scriptURL );
+}
+
+rtl::OUString CustomToolBarImportHelper::MSOCommandToOOCommand( sal_Int16 msoCmd )
+{
+    rtl::OUString result;
+    if ( pMSOCmdConvertor.get() )
+        result = pMSOCmdConvertor->MSOCommandToOOCommand( msoCmd );
+    return result;
+}
+
+rtl::OUString CustomToolBarImportHelper::MSOTCIDToOOCommand( sal_Int16 msoTCID )
+{
+    rtl::OUString result;
+    if ( pMSOCmdConvertor.get() )
+        result = pMSOCmdConvertor->MSOTCIDToOOCommand( msoTCID );
+    return result;
+}
+
+bool
+CustomToolBarImportHelper::createMenu( const rtl::OUString& rName, const uno::Reference< container::XIndexAccess >& xMenuDesc, bool bPersist )
+{
+    bool bRes = true;
+    try
+    {
+        uno::Reference< ui::XUIConfigurationManager > xCfgManager( getCfgManager() );
+        rtl::OUString sMenuBar( RTL_CONSTASCII_USTRINGPARAM("private:resource/menubar/") );
+        sMenuBar += rName;
+        uno::Reference< container::XIndexContainer > xPopup( xCfgManager->createSettings(), uno::UNO_QUERY_THROW );
+        uno::Reference< beans::XPropertySet > xProps( xPopup, uno::UNO_QUERY_THROW ); 
+        // set name for menubar
+        xProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("UIName") ), uno::makeAny( rName ) );
+        if ( xPopup.is() )
+        {
+            uno::Sequence< beans::PropertyValue > aPopupMenu( 4 );
+            aPopupMenu[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CommandURL") );
+            aPopupMenu[0].Value = uno::makeAny( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("vnd.openoffice.org:") ) + rName );
+            aPopupMenu[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Label") );
+            aPopupMenu[1].Value <<= rName;
+            aPopupMenu[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ItemDescriptorContainer") );
+            aPopupMenu[2].Value = uno::makeAny( xMenuDesc );
+            aPopupMenu[3].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Type" ) );
+            aPopupMenu[3].Value <<= sal_Int32( 0 );
+            
+            xPopup->insertByIndex( xPopup->getCount(), uno::makeAny( aPopupMenu ) );
+            if ( bPersist )
+            {
+                xCfgManager->insertSettings( sMenuBar, uno::Reference< container::XIndexAccess >( xPopup, uno::UNO_QUERY ) );
+                uno::Reference< ui::XUIConfigurationPersistence > xPersistence( xCfgManager, uno::UNO_QUERY_THROW );
+                xPersistence->store();
+            }
+        }
+    }
+    catch( uno::Exception& )
+    {
+        bRes = false;
+    }
+    return bRes;
+}
+
+void
+TBBase::indent_printf( FILE* fp, const char* format, ... )
+{
+   va_list ap;
+   va_start ( ap, format );
+
+   // indent nIndent spaces
+   for ( int i=0; i<nIndent; ++i)
+      fprintf(fp," ");
+   // append the rest of the message
+   vfprintf( fp, format, ap );
+   va_end( ap );
+}
+
+rtl::OUString TBBase::readUnicodeString( SvStream* pS, sal_Int32 nChars )
+{
+    sal_Int32 nBufSize = nChars * 2;
+    boost::scoped_array< sal_uInt8 > pArray( new sal_uInt8[ nBufSize ] );
+    pS->Read( pArray.get(), nBufSize );
+    return svt::BinFilterUtils::CreateOUStringFromUniStringArray(  reinterpret_cast< const char* >( pArray.get() ), nBufSize );
+}
+
+TBCHeader::TBCHeader() : bSignature( 0x3 )
+,bVersion( 0x01 )
+,bFlagsTCR( 0 )
+,tct(0x1) // default to Button
+,tcid(0)
+,tbct(0)
+{
+}
+
+
+TBCHeader::~TBCHeader()
+{
+}
+
+bool TBCHeader::Read( SvStream* pS )
+{
+    OSL_TRACE("TBCHeader::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    *pS >> bSignature >> bVersion >> bFlagsTCR >> tct >> tcid >> tbct >> bPriority;
+    //  bit 4 ( from lsb ) 
+    if ( bFlagsTCR & 0x10 )
+    {
+        width.reset( new sal_uInt16 );
+        height.reset( new sal_uInt16 );
+        *pS >> *width >> *height;
+    }
+    return true;
+}
+
+void TBCHeader::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf(fp,"[ 0x%x ] TBCHeader -- dump\n", nOffSet );
+    indent_printf(fp,"  bSignature 0x%x\n", bSignature );
+    indent_printf(fp,"  bVersion 0x%x\n", bVersion );
+    indent_printf(fp,"  bFlagsTCR 0x%x\n", bFlagsTCR );
+    indent_printf(fp,"  tct 0x%x\n", tct );
+    indent_printf(fp,"  tcid 0x%x\n", tcid );
+    indent_printf(fp,"  tbct 0x%x\n", static_cast< unsigned int >( tbct ));
+    indent_printf(fp,"  bPriority 0x%x\n", bPriority );
+    if ( width.get() )
+        indent_printf(fp,"  width 0x%d(0x%x)\n", *width, *width);
+    if ( height.get() )
+        indent_printf(fp,"  height 0x%d(0x%x)\n", *height, *height);
+}
+
+TBCData::TBCData( const TBCHeader& Header ) : rHeader( Header )
+{
+}
+
+bool TBCData::Read(SvStream *pS)
+{
+    OSL_TRACE("TBCData::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    if ( !controlGeneralInfo.Read(pS) /*|| !controlSpecificInfo.Read(pS)*/ )
+        return false;
+    switch ( rHeader.getTct() )
+    {
+        case 0x01: // (Button control)
+        case 0x10: // (ExpandingGrid control)
+            controlSpecificInfo.reset( new TBCBSpecific() );
+            break;
+        case 0x0A: // (Popup control)
+        case 0x0C: // (ButtonPopup control)
+        case 0x0D: // (SplitButtonPopup control)
+        case 0x0E: // (SplitButtonMRUPopup control)
+            controlSpecificInfo.reset( new TBCMenuSpecific() );
+            break;
+        case 0x02: // (Edit control)
+        case 0x04: // (ComboBox control)
+        case 0x14: // (GraphicCombo control)
+        case 0x03: // (DropDown control)
+        case 0x06: // (SplitDropDown control)
+        case 0x09: // (GraphicDropDown control)
+            controlSpecificInfo.reset( new TBCComboDropdownSpecific( rHeader ) );
+            break;
+        default:
+            break;
+    }
+    if ( controlSpecificInfo.get() )
+        return controlSpecificInfo->Read( pS );
+    //#FIXME I need to be able to handle different controlSpecificInfo types.
+    return true;
+}
+
+TBCMenuSpecific* TBCData::getMenuSpecific()
+{
+    TBCMenuSpecific* pMenu = dynamic_cast< TBCMenuSpecific* >( controlSpecificInfo.get() );
+    return pMenu;
+}
+bool TBCData::ImportToolBarControl( CustomToolBarImportHelper& helper, std::vector< css::beans::PropertyValue >& props, bool& bBeginGroup, bool bIsMenuBar )
+{
+    sal_uInt16  nStyle = 0;
+    bBeginGroup = rHeader.isBeginGroup();
+    controlGeneralInfo.ImportToolBarControlData( helper, props );
+    beans::PropertyValue aProp;
+    aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Visible") ) ;
+    aProp.Value = uno::makeAny( rHeader.isVisible() ); // where is the visible attribute stored
+    props.push_back( aProp );
+    if ( rHeader.getTct() == 0x01
+    || rHeader.getTct() == 0x10 )
+    {
+        TBCBSpecific* pSpecificInfo = dynamic_cast< TBCBSpecific* >( controlSpecificInfo.get() );
+        if ( pSpecificInfo )
+        {
+            // if we have a icon then lets  set it for the command 
+            rtl::OUString sCommand;
+            for ( std::vector< css::beans::PropertyValue >::iterator it = props.begin(); it != props.end(); ++it )
+            {
+                if ( it->Name.equals( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CommandURL") ) ) )
+                    it->Value >>= sCommand;
+            }
+            if ( TBCBitMap* pIcon = pSpecificInfo->getIcon() )
+            {
+                // Without a command openoffice won't display the icon
+                if ( sCommand.getLength() )
+                {    
+                    BitmapEx aBitEx( pIcon->getBitMap() );
+                    if ( pSpecificInfo->getIconMask() )
+                         // according to the spec:
+                         // "the iconMask is white in all the areas in which the icon is
+                         // displayed as transparent and is black in all other areas."
+                         aBitEx = BitmapEx( aBitEx.GetBitmap(), pSpecificInfo->getIconMask()->getBitMap().CreateMask( Color( COL_WHITE ) ) );
+    
+                    Graphic aGraphic( aBitEx );
+                    helper.addIcon( aGraphic.GetXGraphic(), sCommand );
+                }
+            }
+            else if ( pSpecificInfo->getBtnFace() )
+            {
+               
+                rtl::OUString sBuiltInCmd = helper.MSOTCIDToOOCommand(  *pSpecificInfo->getBtnFace() );
+                if ( sBuiltInCmd.getLength() )
+                {
+                    uno::Sequence< rtl::OUString> sCmds(1);
+                    sCmds[ 0 ] = sBuiltInCmd;
+                    uno::Reference< ui::XImageManager > xImageManager( helper.getAppCfgManager()->getImageManager(), uno::UNO_QUERY_THROW );
+                    // 0 = default image size
+                    uno::Sequence< uno::Reference< graphic::XGraphic > > sImages = xImageManager->getImages( 0, sCmds );
+                    if ( sImages.getLength() && sImages[0].is() )
+                        helper.addIcon( sImages[0], sCommand );
+                }
+            }
+        }
+    }
+    else if ( rHeader.getTct() == 0x0a )
+    {
+        aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CommandURL") ) ;
+        rtl::OUString sMenuBar( RTL_CONSTASCII_USTRINGPARAM("private:resource/menubar/") );
+        
+        TBCMenuSpecific* pMenu = getMenuSpecific();
+        if ( pMenu )
+            aProp.Value = uno::makeAny( sMenuBar += pMenu->Name() ); // name of popup
+        nStyle |= ui::ItemStyle::DROP_DOWN;
+        props.push_back( aProp );
+    }
+
+    short icontext =  ( rHeader.getTbct() & 0x03 );
+    aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Style") ) ;
+    if ( bIsMenuBar )
+    {
+        nStyle |= ui::ItemStyle::TEXT;
+        if ( !icontext || icontext == 0x3 )
+            // Text And image
+            nStyle |= ui::ItemStyle::ICON;
+    }
+    else 
+    {
+        if ( ( icontext & 0x02 ) == 0x02 )
+            nStyle |= ui::ItemStyle::TEXT;
+        if ( !icontext || ( icontext & 0x03 ) == 0x03 )
+            nStyle |= ui::ItemStyle::ICON;
+    }
+    aProp.Value <<= nStyle;
+    props.push_back( aProp );
+    return true; // just ignore
+}
+
+void TBCData::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf(fp,"[ 0x%x ] TBCData -- dump\n", nOffSet );
+    indent_printf(fp,"  dumping controlGeneralInfo( TBCGeneralInfo )\n");
+    controlGeneralInfo.Print( fp );
+    //if ( rHeader.getTct() == 1 )
+    if ( controlSpecificInfo.get() )
+    {
+        indent_printf(fp,"  dumping controlSpecificInfo( TBCBSpecificInfo )\n");
+        controlSpecificInfo->Print( fp );
+    }
+}
+
+bool
+WString::Read( SvStream *pS )
+{
+    OSL_TRACE("WString::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    sal_Int8 nChars = 0;
+    *pS >> nChars;
+    sString = readUnicodeString( pS, static_cast< sal_Int32 >( nChars  ) );
+    return true;
+}
+
+TBCExtraInfo::TBCExtraInfo() : idHelpContext( 0 )
+{
+}
+
+bool
+TBCExtraInfo::Read( SvStream *pS )
+{
+    OSL_TRACE("TBCExtraInfo::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    if( !wstrHelpFile.Read( pS )  )
+        return false;
+
+    *pS >> idHelpContext;
+
+    if ( !wstrTag.Read( pS ) || !wstrOnAction.Read( pS ) || !wstrParam.Read( pS ) )
+        return false;
+
+    *pS >> tbcu >> tbmg;    
+    return true;
+}
+
+void
+TBCExtraInfo::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf( fp, "[ 0x%x ] TBCExtraInfo -- dump\n", nOffSet );
+    indent_printf( fp, "  wstrHelpFile %s\n", 
+        rtl::OUStringToOString( wstrHelpFile.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+    indent_printf( fp, "  idHelpContext 0x%x\n", static_cast< unsigned int >( idHelpContext ) );
+    indent_printf( fp, "  wstrTag %s\n", 
+        rtl::OUStringToOString( wstrTag.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+    indent_printf( fp, "  wstrOnAction %s\n", 
+        rtl::OUStringToOString( wstrOnAction.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+    indent_printf( fp, "  wstrParam %s\n", 
+        rtl::OUStringToOString( wstrParam.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+    indent_printf( fp, "  tbcu 0x%x\n", tbcu );
+    indent_printf( fp, "  tbmg 0x%x\n", tbmg );
+    
+}
+
+rtl::OUString
+TBCExtraInfo::getOnAction()
+{
+    return wstrOnAction.getString();
+}
+
+TBCGeneralInfo::TBCGeneralInfo() : bFlags( 0 )
+{
+}
+
+bool TBCGeneralInfo::Read( SvStream *pS )
+{
+    OSL_TRACE("TBCGeneralInfo::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    *pS >> bFlags;
+
+    if ( ( bFlags & 0x1 ) && !customText.Read( pS ) )
+        return false;
+    if ( ( bFlags & 0x2 ) && ( !descriptionText.Read( pS ) ||  !tooltip.Read( pS ) ) )
+        return false;
+    if ( ( bFlags & 0x4 ) && !extraInfo.Read( pS ) )
+        return false;
+    return true;
+}
+
+void 
+TBCGeneralInfo::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf( fp, "[ 0x%x ] TBCGeneralInfo -- dump\n", nOffSet );
+    indent_printf( fp, "  bFlags 0x%x\n", bFlags );
+    indent_printf( fp, "  customText %s\n", 
+        rtl::OUStringToOString( customText.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+    indent_printf( fp, "  description %s\n", 
+        rtl::OUStringToOString( descriptionText.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+    indent_printf( fp, "  tooltip %s\n", 
+        rtl::OUStringToOString( tooltip.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+    if ( bFlags & 0x4 ) 
+        extraInfo.Print( fp );
+}
+
+bool 
+TBCGeneralInfo::ImportToolBarControlData( CustomToolBarImportHelper& helper, std::vector< beans::PropertyValue >& sControlData )
+{
+    if ( ( bFlags & 0x5 ) )
+    {
+        beans::PropertyValue aProp;
+        // probably access to the header would be a better test than seeing if there is an action, e.g.
+        // if ( rHeader.getTct() == 0x01 && rHeader.getTcID() == 0x01 ) // not defined, probably this is a command
+        if ( extraInfo.getOnAction().getLength() )
+        {
+            aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CommandURL") );
+            ooo::vba::VBAMacroResolvedInfo aMacroInf = ooo::vba::resolveVBAMacro( &helper.GetDocShell(), extraInfo.getOnAction(), true );
+            if ( aMacroInf.IsResolved() )
+                aProp.Value = helper.createCommandFromMacro( aMacroInf.ResolvedMacro() );
+            else
+                aProp.Value <<= rtl::OUString::createFromAscii("UnResolvedMacro[").concat( extraInfo.getOnAction() ).concat( rtl::OUString::createFromAscii("]") );
+            sControlData.push_back( aProp );
+        }
+
+        aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Label") );
+        aProp.Value = uno::makeAny( customText.getString().replace('&','~') );
+        sControlData.push_back( aProp );
+
+        aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Type") );
+        aProp.Value = uno::makeAny( ui::ItemType::DEFAULT ); 
+        sControlData.push_back( aProp );
+
+        aProp.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Tooltip") );
+        aProp.Value = uno::makeAny( tooltip.getString() ); 
+        sControlData.push_back( aProp );
+/*
+aToolbarItem(0).Name = "CommandURL" wstrOnAction
+aToolbarItem(0).Value = Command
+aToolbarItem(1).Name = "Label"      customText
+aToolbarItem(1).Value = Label
+aToolbarItem(2).Name = "Type"
+aToolbarItem(2).Value = 0
+aToolbarItem(3).Name = "Visible"
+aToolbarItem(3).Value = true        
+*/
+    }
+    return true;
+}
+
+TBCMenuSpecific::TBCMenuSpecific() : tbid( 0 )
+{
+}
+
+bool
+TBCMenuSpecific::Read( SvStream *pS)
+{
+    OSL_TRACE("TBCMenuSpecific::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    *pS >> tbid;
+    if ( tbid == 1 ) 
+    {
+        name.reset( new WString() );
+        return name->Read( pS );
+    }
+    return true;
+}
+
+void 
+TBCMenuSpecific::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf( fp, "[ 0x%x ] TBCMenuSpecific -- dump\n", nOffSet );
+    indent_printf( fp, "  tbid 0x%x\n", static_cast< unsigned int >( tbid ) );
+    if ( tbid == 1 )
+        indent_printf( fp, "  name %s\n", rtl::OUStringToOString( name->getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+
+}
+
+rtl::OUString TBCMenuSpecific::Name()
+{
+    rtl::OUString aName;
+    if ( name.get() )
+        aName = name->getString();
+    return aName;
+}
+TBCBSpecific::TBCBSpecific() : bFlags( 0 )
+{
+}
+
+bool TBCBSpecific::Read( SvStream *pS)
+{
+    OSL_TRACE("TBCBSpecific::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    *pS >> bFlags;
+
+    // bFlags determines what we read next
+
+    // bFlags.fCustomBitmap = 1 ( 0x8 ) set 
+    if ( bFlags & 0x8 )
+    {
+        icon.reset( new TBCBitMap() );
+        iconMask.reset( new TBCBitMap() );
+        if ( !icon->Read( pS ) || !iconMask->Read( pS ) )
+            return false;
+    }
+    // if bFlags.fCustomBtnFace = 1 ( 0x10 )
+    if ( bFlags & 0x10 )
+    {
+        iBtnFace.reset( new sal_uInt16 );
+        *pS >> *iBtnFace.get();
+    }
+    // if bFlags.fAccelerator equals 1 ( 0x04 )
+    if ( bFlags & 0x04 )
+    {
+        wstrAcc.reset( new WString() );
+        return wstrAcc->Read( pS );
+    }
+    return true;
+}
+
+
+void TBCBSpecific::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf( fp, "[ 0x%x ] TBCBSpecific -- dump\n", nOffSet );
+    indent_printf( fp, "  bFlags 0x%x\n", bFlags );
+    bool bResult = ( icon.get() != NULL );
+    indent_printf( fp, "  icon present? %s\n", bResult ? "true" : "false" );
+    if ( bResult )
+    {
+        Indent b;
+        indent_printf( fp, "  icon: \n");
+        icon->Print( fp ); // will dump size
+    }
+    bResult = ( iconMask.get() != NULL );
+    indent_printf( fp, "  icon mask present? %s\n", bResult ? "true" : "false" );
+    if ( bResult )
+    {
+        Indent c;
+        indent_printf( fp, "  icon mask: \n");
+        iconMask->Print( fp ); // will dump size
+    }
+    if ( iBtnFace.get() )
+    {
+        indent_printf( fp, "  iBtnFace 0x%x\n", *(iBtnFace.get()) );
+    }
+    bResult = ( wstrAcc.get() != NULL );
+    indent_printf( fp, "  option string present? %s ->%s<-\n", bResult ? "true" : "false", bResult ? rtl::OUStringToOString( wstrAcc->getString(), RTL_TEXTENCODING_UTF8 ).getStr() : "N/A" );
+}
+
+TBCBitMap* 
+TBCBSpecific::getIcon()
+{
+    return icon.get();
+}
+
+TBCBitMap* 
+TBCBSpecific::getIconMask()
+{
+    return iconMask.get();
+}
+
+TBCComboDropdownSpecific::TBCComboDropdownSpecific(const TBCHeader& header ) 
+{
+    if ( header.getTcID() == 0x01 )
+        data.reset( new TBCCDData() );
+}
+
+bool TBCComboDropdownSpecific::Read( SvStream *pS)
+{
+    nOffSet = pS->Tell();
+    if ( data.get() )
+        return data->Read( pS );
+    return true;
+}
+
+void TBCComboDropdownSpecific::Print( FILE* fp)
+{
+    Indent a;
+    indent_printf(fp,"[ 0x%x ] TBCComboDropdownSpecific -- dump\n", nOffSet );
+    if ( data.get() )
+        data->Print( fp );
+    else
+        indent_printf(fp," no data " );
+}
+
+TBCCDData::TBCCDData() : cwstrItems( 0 )
+,iSel( 0 )
+,cLines( 0 )
+,dxWidth( 0 )
+{
+}
+
+TBCCDData::~TBCCDData()
+{
+}
+
+bool TBCCDData::Read( SvStream *pS)
+{
+    nOffSet = pS->Tell();
+    *pS >> cwstrItems;
+    if ( cwstrItems )
+    {
+        for( sal_Int32 index=0; index < cwstrItems; ++index )
+        {
+            WString aString;
+            if ( !aString.Read( pS ) )
+                return false;
+            wstrList.push_back( aString );
+        } 
+    }
+    *pS >> cwstrMRU >> iSel >> cLines >> dxWidth;
+
+    return wstrEdit.Read( pS );
+}
+
+void TBCCDData::Print( FILE* fp)
+{
+    Indent a;
+    indent_printf(fp,"[ 0x%x ] TBCCDData -- dump\n", nOffSet );
+    indent_printf(fp,"  cwstrItems items in wstrList 0x%d\n", cwstrItems);
+    for ( sal_Int32 index=0; index < cwstrItems; ++index )
+    {
+        Indent b;
+        indent_printf(fp, "  wstrList[%d] %s", static_cast< int >( index ), rtl::OUStringToOString( wstrList[index].getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+    }
+    indent_printf(fp,"  cwstrMRU num most recently used string 0x%d item\n", cwstrMRU);
+    indent_printf(fp,"  iSel index of selected item 0x%d item\n", iSel);
+    indent_printf(fp,"  cLines num of suggested lines to display 0x%d", cLines);
+    indent_printf(fp,"  dxWidth width in pixels 0x%d", dxWidth);
+    indent_printf(fp,"  wstrEdit %s", rtl::OUStringToOString( wstrEdit.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+}
+
+TBCBitMap::TBCBitMap() : cbDIB( 0 ), size( 0 )
+{
+}
+
+TBCBitMap::~TBCBitMap()
+{
+}
+
+// #FIXME Const-ness
+Bitmap& 
+TBCBitMap::getBitMap()
+{
+    return mBitMap;
+}
+
+bool TBCBitMap::Read( SvStream* pS)
+{
+    OSL_TRACE("TBCBitMap::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    *pS >> cbDIB;
+    // cbDIB = sizeOf(biHeader) + sizeOf(colors) + sizeOf(bitmapData) + 10
+    return mBitMap.Read( *pS, FALSE, TRUE );
+}
+
+void TBCBitMap::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf(fp, "[ 0x%x ] TBCBitMap -- dump\n", nOffSet );
+    indent_printf(fp, "  TBCBitMap size of bitmap data 0x%x\n", static_cast< unsigned int > ( cbDIB ) );
+}
+
+TB::TB() : bSignature(0x2),
+bVersion(0x1),
+cCL(0),
+ltbid( 0x1 ),
+ltbtr(0),
+cRowsDefault( 0 ),
+bFlags( 0 )
+{
+}
+
+bool TB::Read(SvStream *pS)
+{
+    OSL_TRACE("TB::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    *pS >> bSignature >> bVersion >> cCL >> ltbid >> ltbtr >> cRowsDefault >> bFlags;
+    name.Read( pS );
+    return true;
+ 
+}
+
+bool TB::IsEnabled()
+{
+    return ( bFlags & 0x01 ) != 0x01;
+}
+
+bool TB::NeedsPositioning()
+{
+    return ( bFlags & 0x10 ) == 0x10;
+}
+
+void TB::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf(fp,"[ 0x%x ] TB -- dump\n", nOffSet );
+    indent_printf(fp,"  bSignature 0x%x\n", bSignature );
+    indent_printf(fp,"  bVersion 0x%x\n", bVersion );
+    indent_printf(fp,"  cCL 0x%x\n", cCL );
+    indent_printf(fp,"  ltbid 0x%x\n", ltbid );
+    indent_printf(fp,"  ltbtr 0x%x\n", ltbtr );
+    indent_printf(fp,"  cRowsDefault 0x%x\n", cRowsDefault );
+    indent_printf(fp,"  bFlags 0x%x\n", bFlags );
+    indent_printf(fp, "  name %s\n", rtl::OUStringToOString( name.getString(), RTL_TEXTENCODING_UTF8 ).getStr() );
+}
+
+TBVisualData::TBVisualData() : tbds(0), tbv(0), tbdsDock(0), iRow(0)
+{
+}
+
+bool TBVisualData::Read( SvStream* pS )
+{
+    OSL_TRACE("TBVisualData::Read() stream pos 0x%x", pS->Tell() );
+    nOffSet = pS->Tell();
+    *pS >> tbds >> tbv >> tbdsDock >> iRow;
+    rcDock.Read( pS );
+    rcFloat.Read( pS );
+    return true;
+}
+
+void SRECT::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf( fp, "  left 0x%x\n", left);
+    indent_printf( fp, "  top 0x%x\n", top);
+    indent_printf( fp, "  right 0x%x\n", right);
+    indent_printf( fp, "  bottom 0x%x\n", bottom);
+}
+
+void TBVisualData::Print( FILE* fp )
+{
+    Indent a;
+    indent_printf( fp, "[ 0x%x ] TBVisualData -- dump\n", nOffSet );
+    indent_printf( fp, "  tbds 0x%x\n", tbds);
+    indent_printf( fp, "  tbv  0x%x\n", tbv);
+    indent_printf( fp, "  tbdsDoc  0x%x\n", tbdsDock);
+    indent_printf( fp, "  iRow  0x%x\n", iRow);
+    rcDock.Print( fp );
+    rcFloat.Print( fp );
+}
+
commit 31fdcf4f864006560c7b6045a75b1225facde99a
Author: Noel Power <noel.power at novell.com>
Date:   Wed Oct 6 10:16:19 2010 +0100

    initial commit for vba blob ( not including container_control stuff )

diff --git a/filter/inc/filter/msfilter/escherex.hxx b/filter/inc/filter/msfilter/escherex.hxx
index 53f6f9b..0ee4916 100644
--- a/filter/inc/filter/msfilter/escherex.hxx
+++ b/filter/inc/filter/msfilter/escherex.hxx
@@ -45,6 +45,7 @@
 #include <com/sun/star/drawing/BitmapMode.hpp>
 #include <com/sun/star/drawing/Hatch.hpp>
 #include <svx/msdffdef.hxx>
+#include <memory>
 #include "filter/msfilter/msfilterdllapi.h"
 
         /*Record Name       FBT-Value   Instance                  Contents                                                          Wrd Exl PPt Ver*/
@@ -1305,6 +1306,19 @@ public:
                                     const Rectangle& rRect ) = 0;
 };
 
+class InteractionInfo
+{
+	bool 			mbHasInteraction;
+	std::auto_ptr<SvMemoryStream>		mpHyperlinkRecord;
+	InteractionInfo();
+public:
+	InteractionInfo( SvMemoryStream* pStream, bool bInteraction ) : mbHasInteraction( bInteraction )
+	{
+		mpHyperlinkRecord.reset( pStream );
+	}
+	bool	hasInteraction() { return mbHasInteraction; }
+	const std::auto_ptr< SvMemoryStream >&	getHyperlinkRecord() { return mpHyperlinkRecord; }
+};
 
 class EscherExHostAppData
 {
@@ -1312,14 +1326,17 @@ private:
         EscherExClientAnchor_Base*	pClientAnchor;
         EscherExClientRecord_Base*	pClientData;
         EscherExClientRecord_Base*	pClientTextbox;
+		InteractionInfo*		pInteractionInfo;
         // ignore single shape if entire pages are written
         BOOL						bDontWriteShape;
 
 public:
         EscherExHostAppData() : pClientAnchor(0), pClientData(0),
-                                pClientTextbox(0), bDontWriteShape(FALSE)
+								pClientTextbox(0), pInteractionInfo(0), bDontWriteShape(FALSE)
         {}
 
+		void SetInteractionInfo( InteractionInfo* p )
+			{ pInteractionInfo = p; }
         void SetClientAnchor( EscherExClientAnchor_Base* p )
             { pClientAnchor = p; }
         void SetClientData( EscherExClientRecord_Base* p )
@@ -1328,6 +1345,8 @@ public:
             { pClientTextbox = p; }
         void SetDontWriteShape( BOOL b )
             { bDontWriteShape = b; }
+		InteractionInfo* GetInteractionInfo() const
+			{ return pInteractionInfo; }
         EscherExClientAnchor_Base* GetClientAnchor() const
             { return pClientAnchor; }
         EscherExClientRecord_Base* GetClientData() const
diff --git a/filter/inc/filter/msfilter/msocximex.hxx b/filter/inc/filter/msfilter/msocximex.hxx
index c50c5a4..9caaf39 100644
--- a/filter/inc/filter/msfilter/msocximex.hxx
+++ b/filter/inc/filter/msfilter/msocximex.hxx
@@ -29,6 +29,7 @@
 
 #include <sot/storage.hxx>
 #include <tools/debug.hxx>
+#include <com/sun/star/graphic/XGraphicObject.hpp>
 
 //!! no such defines in global namespaces - it will break other existing code that uses the same define!!
 //#ifndef C2U
@@ -287,7 +288,10 @@ public:
     bool mbVisible;
     UniString sName;
     UniString msToolTip;
+	UniString msParentName;
     OCX_FontData aFontData;
+    rtl::OUString msCtrlSource;
+    rtl::OUString msRowSource;
         SfxObjectShell *pDocSh;
 protected:
 
@@ -324,14 +328,13 @@ public:
     nMultiState(0), nValueLen(0), nCaptionLen(0), nVertPos(1), nHorzPos(7),
     nSpecialEffect(2), nIcon(0), nPicture(0), nAccelerator(0), nGroupNameLen(0),
     pValue(0), pCaption(0), pGroupName(0), nIconLen(0), pIcon(0),
-    nPictureLen(0), pPicture(0) {}
+    nPictureLen(0) {}
 
     ~OCX_ModernControl() {
         if (pValue) delete[] pValue;
         if (pCaption) delete[] pCaption;
         if (pGroupName) delete[] pGroupName;
         if (pIcon) delete[] pIcon;
-        if (pPicture) delete[] pPicture;
     }
     sal_Bool Read(SotStorageStream *pS);
 
@@ -412,7 +415,8 @@ public:
 
     sal_uInt8 pPictureHeader[20];
     sal_uInt32 nPictureLen;
-    sal_uInt8 *pPicture;
+    ::rtl::OUString sImageUrl;
+	com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicObject> mxGrfObj;
 
 };
 
@@ -461,6 +465,7 @@ public:
 
         bool bAutoSize;
         ::rtl::OUString sImageUrl;
+		com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicObject> mxGrfObj;
         sal_Bool Read(SotStorageStream *pS);
 
     using OCX_Control::Import; // to not hide the other two import methods
@@ -485,6 +490,8 @@ struct ContainerRecord
 
     ::rtl::OUString cName;
     ::rtl::OUString controlTip;
+    ::rtl::OUString sCtrlSource;
+    ::rtl::OUString sRowSource;
 
     sal_uInt32 nTop;
     sal_uInt32 nLeft;
@@ -499,54 +506,8 @@ typedef std::vector<OCX_Control*>::iterator CtrlIterator;
 typedef std::vector<OCX_Control*>::const_iterator CtrlIteratorConst;
 typedef std::vector<OCX_Control*>  CtrlList;
 
-
-
-class RBGroup
-{
-    public:
-    RBGroup():mRBGroupPos(0){}
-    RBGroup(sal_uInt16& groupPos ):mRBGroupPos(groupPos){}
-    sal_Int16 tabPos() const { return mRBGroupPos; }
-    std::vector<OCX_Control*>::size_type numControls()
-    { return mpControls.size(); }
-    std::vector<OCX_Control*>& controls() { return mpControls; }
-
-    void add(OCX_Control* pRB);
-    private:
-    sal_uInt16 mRBGroupPos;
-    std::vector<OCX_Control*> mpControls;
-};
-
-typedef ::std::hash_map < ::rtl::OUString, RBGroup*, ::rtl::OUStringHash,
-    ::std::equal_to< ::rtl::OUString > > RBGroupHash;
-typedef std::vector<RBGroup*>::iterator GroupIterator;
-
 class OCX_OptionButton;
 
-class RBGroupManager
-{
-public:
-    RBGroupManager( String& defaultName );
-    ~RBGroupManager();
-
-    CtrlList insertGroupsIntoControlList( const CtrlList& sourceList );
-    void addRadioButton( OCX_OptionButton* pRButton );
-private:
-
-    void addSeperator( std::vector< OCX_Control* >& dest );
-    void copyList( std::vector< OCX_Control* >& src,
-                  std::vector< OCX_Control* >& dest,
-                  bool addGroupSeperator );
-
-    RBGroupHash rbGroups;
-    String mSDefaultName;
-    std::vector< RBGroup* > groupList;
-    sal_uInt16 numRadioButtons;
-};
-
-
-
-
 class OCX_ContainerControl : public OCX_Control
 {
 public:
@@ -572,8 +533,9 @@ public:
         SotStorageStreamRef getContainerStream() { return mContainerStream; }
 
         virtual void ProcessControl( OCX_Control* pControl, SvStorageStream* pS, ContainerRecord& rec );
-        bool createFromContainerRecord( const ContainerRecord& record,
+        bool createFromContainerRecord( ContainerRecord& record,
             OCX_Control*& );
+        SotStorageStreamRef getContainedControlsStream(){ return mContainedControlsStream; }
 protected:
         // This class not meant to be instantiated
         // needs to be subclassed
@@ -585,10 +547,10 @@ protected:
             OCX_Control* pParent = NULL );
         rtl::OUString createSubStreamName( const sal_uInt32& subStorageID );
 
-        RBGroupManager rbGroupMgr;
         com::sun::star::uno::Reference<
                 com::sun::star::container::XNameContainer > mxParent;
     std::vector<OCX_Control*> mpControls;
+        std::hash_map<sal_uInt16, sal_uInt16> mActiveXIDMap;
         SotStorageRef mContainerStorage;
         SotStorageStreamRef mContainerStream;
         SotStorageStreamRef mContainedControlsStream;
@@ -856,7 +818,6 @@ public:
     {
         delete[] pCaption;
         delete[] pIcon;
-        delete[] pPicture;
     }
 
     virtual sal_Bool Read(SvStorageStream *pS);
@@ -920,7 +881,8 @@ public:
 
     sal_uInt8 pPictureHeader[20];
     sal_uInt32  nPictureLen;
-    sal_uInt8 *pPicture;
+    ::rtl::OUString sImageUrl;
+	com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicObject> mxGrfObj;
 private:
         com::sun::star::uno::Reference<
                 com::sun::star::uno::XComponentContext> mxCtx;
@@ -959,7 +921,8 @@ public:
     OCX_OptionButton() : OCX_ModernControl(rtl::OUString::createFromAscii("OptionButton"))
     {
         msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.RadioButton");
-        msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlRadioButtonModel");
+		//msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlRadioButtonModel");
+		msDialogType = rtl::OUString::createFromAscii("com.sun.star.form.component.RadioButton");
         mnBackColor = 0x80000005L;
         mnForeColor = 0x80000008L;
         aFontData.SetHasAlign(TRUE);
@@ -1060,7 +1023,7 @@ class OCX_ComboBox : public OCX_ModernControl
 public:
     OCX_ComboBox() : OCX_ModernControl(rtl::OUString::createFromAscii("ComboBox")){
         msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.ComboBox");
-            msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlComboBoxModel");
+	        msDialogType = rtl::OUString::createFromAscii("com.sun.star.form.component.ComboBox");
         mnBackColor = 0x80000005;
         mnForeColor = 0x80000008;
         nBorderColor = 0x80000006;
@@ -1085,7 +1048,8 @@ class OCX_ListBox : public OCX_ModernControl
 public:
     OCX_ListBox() : OCX_ModernControl(rtl::OUString::createFromAscii("ListBox")){
         msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.ListBox");
-        msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlListBoxModel");
+		//msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlListBoxModel");
+		msDialogType = rtl::OUString::createFromAscii("com.sun.star.form.component.ListBox");
         mnBackColor = 0x80000005;
         mnForeColor = 0x80000008;
         nBorderColor = 0x80000006;
@@ -1113,7 +1077,7 @@ public:
     fEnabled(1), fLocked(0), fBackStyle(1), fWordWrap(0), fAutoSize(0),
         nCaptionLen(0), nVertPos(1), nHorzPos(7), nMousePointer(0), nPicture(0),
         nAccelerator(0), nIcon(0), pCaption(0), nIconLen(0), pIcon(0), nPictureLen(0),
-        pPicture(0), mbTakeFocus( true )
+        mbTakeFocus( true )
     {
             msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.CommandButton");
             msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlButtonModel");
@@ -1124,7 +1088,6 @@ public:
     ~OCX_CommandButton() {
         if (pCaption) delete[] pCaption;
         if (pIcon) delete[] pIcon;
-        if (pPicture) delete[] pPicture;
     }
     sal_Bool Read(SotStorageStream *pS);
 
@@ -1167,7 +1130,8 @@ public:
 
     sal_uInt8 pPictureHeader[20];
     sal_uInt32  nPictureLen;
-    sal_uInt8 *pPicture;
+    ::rtl::OUString sImageUrl;
+	com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicObject> mxGrfObj;
 
     bool        mbTakeFocus;
 
@@ -1285,7 +1249,7 @@ public:
 
     sal_uInt8 pPictureHeader[20];
     sal_uInt32  nPictureLen;
-    sal_uInt8 *pPicture;
+ 	sal_uInt8 *pPicture;
 
     static OCX_Control *Create() { return new OCX_Label;}
 
diff --git a/filter/inc/filter/msfilter/svxmsbas.hxx b/filter/inc/filter/msfilter/svxmsbas.hxx
index 3a945fe..a619c99 100644
--- a/filter/inc/filter/msfilter/svxmsbas.hxx
+++ b/filter/inc/filter/msfilter/svxmsbas.hxx
@@ -32,6 +32,8 @@
 #include "filter/msfilter/msfilterdllapi.h"
 
 #include <sot/storage.hxx>
+#include <map>
+#include <hash_map>
 
 class SfxObjectShell;
 
@@ -50,6 +52,12 @@ class SfxObjectShell;
  * probably what the user expects to see when viewing the code
  */
 
+typedef std::hash_map< sal_Int32, String >  ObjIdToName;
+
+typedef std::map< String, ObjIdToName >  ControlAttributeInfo;
+
+class VBA_Impl;
+
 class MSFILTER_DLLPUBLIC SvxImportMSVBasic
 {
 public:
@@ -76,23 +84,31 @@ public:
 
     // check if the MS-VBA-Storage exist in the RootStorage of the DocShell.
     // If it exist, then return the WarningId for loosing the information.
+
+        const ControlAttributeInfo& ControlNameForObjectId(){ return m_ModuleNameToObjIdHash; }
     static ULONG GetSaveWarningOfMSVBAStorage( SfxObjectShell &rDocS );
 
     static String GetMSBasicStorageName();
+        rtl::OUString GetVBAProjectName() { return msProjectName; }
 private:
     SotStorageRef xRoot;
     SfxObjectShell &rDocSh;
     BOOL bImport;
     BOOL bCopy;
+	ControlAttributeInfo m_ModuleNameToObjIdHash;
+	MSFILTER_DLLPRIVATE void extractAttribute( const String& rAttribute, const String& rModName );
 
     MSFILTER_DLLPRIVATE BOOL ImportCode_Impl( const String& rStorageName,
                           const String &rSubStorageName,
                           const std::vector< String >& codeNames,
                           BOOL bAsComment, BOOL bStripped);
     MSFILTER_DLLPRIVATE bool ImportForms_Impl(const String& rStorageName, 
-        const String &rSubStorageName);
+		const String &rSubStorageName, BOOL bVBAMode);
     MSFILTER_DLLPRIVATE BOOL CopyStorage_Impl( const String& rStorageName,
                            const String &rSubStorageName);
+        rtl::OUString msProjectName;
+	MSFILTER_DLLPRIVATE BOOL ImportCode_Impl( VBA_Impl&, const std::vector< String >&, BOOL, BOOL );
+	MSFILTER_DLLPRIVATE bool ImportForms_Impl( VBA_Impl&, const String&, const String&, BOOL);
 };
 
 #endif
diff --git a/filter/source/msfilter/eschesdo.cxx b/filter/source/msfilter/eschesdo.cxx
index 85077e0..f514a87 100644
--- a/filter/source/msfilter/eschesdo.cxx
+++ b/filter/source/msfilter/eschesdo.cxx
@@ -245,6 +245,19 @@ UINT32 ImplEESdrWriter::ImplWriteShape( ImplEESdrObject& rObj,
         // #i51348# shape name
         if( aShapeName.Len() > 0 )
             aPropOpt.AddOpt( ESCHER_Prop_wzName, aShapeName );
+        if ( InteractionInfo* pInteraction = mpHostAppData->GetInteractionInfo() )
+		{
+			const std::auto_ptr< SvMemoryStream >& pMemStrm = pInteraction->getHyperlinkRecord();
+			if ( pMemStrm.get() )
+			{
+				pMemStrm->ObjectOwnsMemory( FALSE );
+				sal_uInt8* pBuf = (sal_uInt8*) pMemStrm->GetData();
+				sal_uInt32 nSize = pMemStrm->Seek( STREAM_SEEK_TO_END );
+				aPropOpt.AddOpt( ESCHER_Prop_pihlShape, sal_False, nSize, pBuf, nSize );;       
+			}
+			if ( pInteraction->hasInteraction() )
+				aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x00080008 );       
+        }
 
         if ( rObj.GetType().EqualsAscii( "drawing.Custom" ) )
         {
diff --git a/filter/source/msfilter/makefile.mk b/filter/source/msfilter/makefile.mk
index 7780529..c59a126 100644
--- a/filter/source/msfilter/makefile.mk
+++ b/filter/source/msfilter/makefile.mk
@@ -53,6 +53,7 @@ SLOFILES= \
     $(SLO)$/svdfppt.obj		\
     $(SLO)$/svxmsbas2.obj \
     $(SLO)$/msvbahelper.obj \
+	$(SLO)$/mstoolbar.obj\
 
 SHL1TARGET= msfilter$(DLLPOSTFIX)
 SHL1IMPLIB=	i$(TARGET)
@@ -61,6 +62,7 @@ SHL1USE_EXPORTS=name
 SHL1STDLIBS= \
              $(EDITENGLIB) \
              $(SVXCORELIB) \
+             $(SVTOOLLIB) \
              $(SFX2LIB) \
              $(XMLOFFLIB) \
              $(BASEGFXLIB) \
diff --git a/filter/source/msfilter/msocximex.cxx b/filter/source/msfilter/msocximex.cxx
index b90a876..6a0bd13 100644
--- a/filter/source/msfilter/msocximex.cxx
+++ b/filter/source/msfilter/msocximex.cxx
@@ -45,6 +45,10 @@
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <com/sun/star/form/XFormsSupplier.hpp>
 #include <com/sun/star/form/XForm.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
 #include <com/sun/star/form/FormComponentType.hpp>
 #include <com/sun/star/awt/FontWeight.hpp>
 #include <com/sun/star/awt/FontSlant.hpp>
@@ -69,7 +73,22 @@
 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
 #include <algorithm>
 #include <memory>
-
+#include <com/sun/star/graphic/GraphicObject.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <comphelper/componentcontext.hxx>
+#include <unotools/streamwrap.hxx>
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <svtools/filterutils.hxx>
+ 
 #ifndef C2S
 #define C2S(cChar)	String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(cChar))
 #endif
@@ -83,6 +102,7 @@ using namespace cppu;
 
 
 #define WW8_ASCII2STR(s) String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(s))
+#define GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
 
 
 static char sWW8_form[] = "WW-Standard";
@@ -111,126 +131,48 @@ long ReadAlign(SvStorageStream *pS, long nPos, int nAmount)
     return 0;
 }
 
-
 // NP - Images in controls in OO2.0/SO8 exist as links, e.g. they are not part of the document so are
 // referenced externally. On import from ms document try to save images for controls here.
 // Images are stored in directory called temp in the user installation directory. Next version of OO/SO
 // hopefully will address this issue and allow a choice e.g. images for controls to be stored as links
 // or embeded in the document.
-
-// [out]location     path to the stream to where the image is to be stored,
-//               if same name exists in folder then this function calcuates a new name
-// [in] data     raw bytes of image to be stored.
-// [in] dataLen  no. byte to be stored
-//
-// returns, true if successful
-
-bool storePictureInFileSystem( OUString& location, sal_uInt8* data, sal_uInt32 dataLen )
-{
-    bool result = true;
-    OUString origPath = location;
-    try
-    {
-        uno::Reference<lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory(),
-                                                      uno::UNO_QUERY_THROW );
-        uno::Reference< com::sun::star::ucb::XSimpleFileAccess> xSFA( xMSF->createInstance(
-                                                       S2U("com.sun.star.ucb.SimpleFileAccess" ) ),
-                                                       uno::UNO_QUERY_THROW );
-        OUString ext;
-        sal_Int32 index = 0;
-        while (  xSFA->exists( location ) )
-        {
-            ext = OUString::valueOf( ++index );
-            location = origPath + ext;
-        }
-
-        SvStream*  pStream = ::utl::UcbStreamHelper::CreateStream( location, STREAM_WRITE | STREAM_TRUNC );
-        if ( pStream )
-        {
-            pStream->Write(data, dataLen);
-            delete pStream;
-        }
-        else
-        {
-            result = false;
-        }
-    }
-    catch( uno::Exception& )
-    {
-        result = false;
-    }
-    return result;
+uno::Reference< graphic::XGraphicObject> lcl_readGraphicObject( SotStorageStream *pS )
+{
+	uno::Reference< graphic::XGraphicObject > xGrfObj;
+	uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+	if( xServiceManager.is() )
+	{
+		try
+		{
+			// use the GraphicProvider service to get the XGraphic
+			uno::Reference< graphic::XGraphicProvider > xGraphProvider(
+					xServiceManager->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ), uno::UNO_QUERY );
+			if( xGraphProvider.is() )
+			{
+				uno::Reference< io::XInputStream > xStream( new utl::OInputStreamWrapper( *pS ) );
+				if( xStream.is() )
+				{
+					uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
+					aMediaProps[0].Name = ::rtl::OUString::createFromAscii( "InputStream" );
+					aMediaProps[0].Value <<= xStream;
+					uno::Reference< graphic::XGraphic > xGraphic = xGraphProvider->queryGraphic( aMediaProps );
+					if( xGraphic.is() )
+					{
+						// create an XGraphicObject
+						::comphelper::ComponentContext aContext( xServiceManager );
+						xGrfObj = graphic::GraphicObject::create( aContext.getUNOContext() );
+						xGrfObj->setGraphic(xGraphic);
+					}
+				}
+			}
+		}
+		catch( uno::Exception& )
+		{
+		}
+	}
+	return xGrfObj;
 }
 
-// NP - Images in controls in OO2.0/SO8 exist as links, e.g. they are not part of the document so are
-// referenced externally. On import from ms document try to save images from controls here so this
-// at least a macro programmer has a chance to accessed them manually later. Next version of OO/SO
-// hopefully will address this issue.
-// Images will be stored in a top level folder in the document package, folder is named "MigratedImages"
-
-// [in] pDocSh*  the document shell.
-// [in] name     name of stream image to stored in.
-// [in] data     raw bytes of image to be stored.
-// [in] dataLen  no. byte to be stored
-
-bool storePictureInDoc( SfxObjectShell* pDocSh, OUString& name, sal_uInt8* data, sal_uInt32 dataLen )
-{
-    uno::Reference < embed::XStorage > xStor;
-    if (pDocSh)
-    {
-        xStor = pDocSh->GetStorage();
-        if( xStor.is() )
-        {
-            try
-            {
-                uno::Reference< embed::XStorage > xPictures = xStor->openStorageElement(
-                    OUString( RTL_CONSTASCII_USTRINGPARAM( "MigratedImages" ) ),
-                    embed::ElementModes::READWRITE );
-                uno::Reference< beans::XPropertySet > xPropSet( xPictures, uno::UNO_QUERY );
-
-                // Set media type of folder MigratedImages to something ( that is unknown ) so that
-                // it will get copied to exported OO/SO format after SaveAs
-                if ( xPropSet.is() )
-                {
-                    OUString aMediaType = C2U("MigrationImages");
-                    uno::Any a;
-                    a <<= aMediaType;
-                    xPropSet->setPropertyValue( C2U("MediaType"), a );
-                }
-
-                uno::Reference< io::XStream > xObjReplStr = xPictures->openStreamElement(
-                        name,
-                        embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
-                uno::Reference< io::XOutputStream > xOutStream( xObjReplStr->getOutputStream(), uno::UNO_QUERY_THROW );
-                uno::Sequence< sal_Int8 > imageBytes( (sal_Int8*)data, dataLen );
-                xOutStream->writeBytes( imageBytes );
-                xOutStream->closeOutput();
-
-                uno::Reference< embed::XTransactedObject > xTransact( xPictures, uno::UNO_QUERY );
-                if ( xTransact.is() )
-                {
-                    xTransact->commit();
-                }
-            }
-            catch( uno::Exception& )
-            {
-                return false;
-            }
-
-        }
-        else
-        {
-            // no storage something wrong
-            return false;
-        }
-    }
-    else
-    {
-        //No doc shell
-        return false;
-    }
-    return true;
-}
 
 long WriteAlign(SvStorageStream *pS, int nAmount)
 {
@@ -394,35 +336,11 @@ void lclReadCharArray( SvStorageStream& rStrm, char*& rpcCharArr, sal_uInt32 nLe
  */
 OUString lclCreateOUString( const char* pcCharArr, sal_uInt32 nLenFld )
 {
-    OUStringBuffer aBuffer;
     sal_uInt32 nBufSize = lclGetBufferSize( nLenFld );
     if( lclIsCompressed( nLenFld ) )
-    {
-        // buffer contains compressed Unicode, not encoded bytestring
-        sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufSize );
-        aBuffer.setLength( nStrLen );
-        const char* pcCurrChar = pcCharArr;
-        for( sal_Int32 nChar = 0; nChar < nStrLen; ++nChar, ++pcCurrChar )
-            /*  *pcCurrChar may contain negative values and therefore MUST be
-                casted to unsigned char, before assigned to a sal_Unicode. */
-            aBuffer.setCharAt( nChar, static_cast< unsigned char >( *pcCurrChar ) );
-    }
-    else
-    {
-        // buffer contains Little-Endian Unicode
-        sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufSize ) / 2;
-        aBuffer.setLength( nStrLen );
-        const char* pcCurrChar = pcCharArr;
-        for( sal_Int32 nChar = 0; nChar < nStrLen; ++nChar )
-        {
-            /*  *pcCurrChar may contain negative values and therefore MUST be
-                casted to unsigned char, before assigned to a sal_Unicode. */
-            sal_Unicode cChar = static_cast< unsigned char >( *pcCurrChar++ );
-            cChar |= (static_cast< unsigned char >( *pcCurrChar++ ) << 8);
-            aBuffer.setCharAt( nChar, cChar );
-        }
-    }
-    return aBuffer.makeStringAndClear();
+        return svt::BinFilterUtils::CreateOUStringFromStringArray( pcCharArr, nBufSize );
+
+    return svt::BinFilterUtils::CreateOUStringFromUniStringArray( pcCharArr, nBufSize );
 }
 
 // export ---------------------------------------------------------------------
@@ -542,8 +460,129 @@ const sal_uInt16 TOGGLEBUTTON = (sal_uInt16)0x1C;
 const sal_uInt16 SCROLLBAR = (sal_uInt16)0x2F;
 
 const sal_uInt16 MULTIPAGE = (sal_uInt16)0x39;
+// The IDs with bit 0x8000 set appear to be generated.
+// It looks like these ID's are used with the non-toolbox [1]
+// ActiveX controls that can be present in a Userform
+// ( note: RefEdit seems to be an exception )
+// In UserForm::Read just before the Container record starts
+// you will notice there can be sometimes trailing records, 
+// it seems that these records have a 1:1 relationship with the non-toolbox
+// controls present in the Userform. An id in the trailing record
+// seems to identify the specific ActiveX control and an artificial nTypeIdent
+// e.g. 0x8000, 0x8001 etc. is created so as to be able to associate
+// the ActiveX control when referenced later 
+// [1] Such ActiveX controls are added via Tools/AddionalControls
+// menu
+
+// create a fixed set of those special id(s)
+// ahem, we can only read one Progress bars at the moment so....
 const sal_uInt16 PROGRESSBAR = (sal_uInt16)0x8000;
 
+// A set of IDs from the trailing records mentioned above that seem to
+// identify the following ActiveX controls 
+// Currently we only can process ( in a limited way ) the ProgressBar
+// the other ID's are for reference ( & future )
+
+// RefEdit control {00024512-0000-0000-c000-000000000046}
+const sal_uInt8 aRefEditID[] =
+{
+0x12, 0x45, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+};
+
+// Microsoft ProgressBar Control, version 6.0 {35053A22-8589-11D1-B16A-00C0F0283628}
+const sal_uInt8 aProgressID[] =
+{
+0x22, 0x3a, 0x05, 0x35, 0x89, 0x85, 0xd1, 0x11,  0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
+};
+
+// Calendar Control 10.0 
+const sal_uInt8 aCalendarID[] =
+{
+0x2b, 0xc9, 0x27, 0x8e, 0x64, 0x12, 0x1c, 0x10, 0x8a, 0x2f, 0x04, 0x02, 0x24, 0x00, 0x9c, 0x02,
+};
+
+
+// Microsoft ImageComboxBox Control, version 6.0 {DD9DA666-8594-11D1-B16A-00C0F0283628}
+const sal_uInt8 aImageComboID[] =
+{
+0x66, 0xa6, 0x9d, 0xdd, 0x94, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
+};
+
+// Microsoft ImageList Control, version 6.0 {2C247F23-8591-11D1-B16A-00C0F0283628}
+const sal_uInt8 aImageListID[] =
+{
+0x23, 0x7f, 0x24, 0x2c, 0x91, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
+};
+
+// Microsoft Slider Control, version 6.0 {F08DF954-8592-11D1-B16A-00C0F0283628}
+const sal_uInt8 aSliderID[] =
+{
+0x54, 0xf9, 0x8d, 0xf0, 0x92, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
+};
+
+// Microsoft StatusBar Control, version 6.0 {8E3867A3-8586-11D1-B16A-00C0F0283628}
+const sal_uInt8 aStatusBarID[] =
+{
+0xa3, 0x67, 0x38, 0x8e, 0x86, 0x85, 0xd1, 0x11, 0xb1, 0x6a, 0x00, 0xc0, 0xf0, 0x28, 0x36, 0x28,
+};
+
+// Microsoft Office Chart 10.0
+const sal_uInt8 aChartSpaceID[] =
+{
+0x46, 0xe5, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+};
+
+const sal_Int16 ActiveXIDLen = 0x10; // CLSID len
+const sal_Int16 ActiveXIDBlockLen = 0x30; // the block len that contains the CLSID
+
+bool lcl_handleActiveXControl(  SvStorageStream *pS, sal_uInt16& nTypeID )
+{
+    nTypeID = 0; // Illegal ActiveX ID 
+    bool bRes = false;
+    sal_uInt16 nIdentifier, nFixedAreaLen;
+    *pS >> nIdentifier;    
+    *pS >> nFixedAreaLen;    
+    pS->SeekRel( ( nFixedAreaLen - ActiveXIDBlockLen ) );
+    sal_uInt8 aID[ ActiveXIDLen ];
+    if ( !pS->IsEof() )
+    {
+        pS->Read( aID, ActiveXIDLen );
+        pS->SeekRel( ActiveXIDBlockLen - ActiveXIDLen ); // read remainer of record
+        if ( memcmp( aID, aProgressID, ActiveXIDLen ) == 0 )
+        {
+            nTypeID = PROGRESSBAR;
+            OSL_TRACE("Found supported ***PROGRESSBAR*** ActiveX control");
+            bRes = true;
+        }
+#if (OSL_DEBUG_LEVEL > 0)
+        // If we really want to process these more controls we should put them in 
+        // a list or array and have a single loop testing each id. For the moment 
+        // as we only can process PROGRESSBAR, not much point doing that until 
+        // we add support for at least another activex control
+
+        else if ( memcmp( aID, aCalendarID, ActiveXIDLen ) == 0 )
+            OSL_TRACE("Found unsupported ***CALENDAR*** ActiveX control");
+        else if ( memcmp( aID, aRefEditID, ActiveXIDLen ) == 0 )
+            OSL_TRACE("Found unsupported ***REFEDIT*** ActiveX control");
+        else if ( memcmp( aID, aImageComboID, ActiveXIDLen ) == 0 )
+            OSL_TRACE("Found unsupported ***IMAGECOMBO*** ActiveX control");
+        else if ( memcmp( aID, aImageListID, ActiveXIDLen ) == 0 )
+            OSL_TRACE("Found unsupported ***IMAGELIST*** ActiveX control");
+        else if ( memcmp( aID, aChartSpaceID, ActiveXIDLen ) == 0 )
+            OSL_TRACE("Found unsupported ***CHARTSPACE*** ActiveX control");
+        else if ( memcmp( aID, aSliderID, ActiveXIDLen ) == 0 )
+            OSL_TRACE("Found unsupported ***SLIDER*** ActiveX control");
+        else if ( memcmp( aID, aStatusBarID, ActiveXIDLen ) == 0 )
+            OSL_TRACE("Found unsupported ***STATUSBAR*** ActiveX control");
+#endif
+        else
+        {
+            OSL_TRACE("Unknown activeX ID !");
+        }
+    }
+    return bRes;
+}
+
 typedef std::vector< ContainerRecord > ContainerRecordList;
 
 class ContainerRecReader
@@ -618,6 +657,8 @@ class ContainerRecReader
             // control type
             if( nContentFlags & 0x00000080 )
                 *pS >> rec.nTypeIdent;
+            if( nContentFlags & 0x00000200 )
+                pS->SeekRel( 4 ); // Grouping?
             // length of infotip
             sal_uInt32 nTipLen = 0;
             if( nContentFlags & 0x00000800 )
@@ -692,14 +733,22 @@ class ContainerRecReader
             if( nCtrlSrcBufSize > 0 )
             {
                 ReadAlign( pS, pS->Tell() - nStartPos, 4 );
-                pS->SeekRel( nCtrlSrcBufSize );
+                std::auto_ptr< sal_Char > pCtrlSrcName;
+                pCtrlSrcName.reset( new sal_Char[ nCtrlSrcBufSize ] );
+                pS->Read( pCtrlSrcName.get(), nCtrlSrcBufSize );
+                rec.sCtrlSource = lclCreateOUString( pCtrlSrcName.get(), nCtrlSrcLen );
+                OSL_TRACE("*** *** *** ControlSourceName -> %s ", rtl::OUStringToOString( rec.sCtrlSource, RTL_TEXTENCODING_UTF8 ).getStr() );
             }
             // row source name
             sal_uInt32 nRowSrcBufSize = lclGetBufferSize( nRowSrcLen );
             if( nRowSrcBufSize > 0 )
             {
                 ReadAlign( pS, pS->Tell() - nStartPos, 4 );
-                pS->SeekRel( nRowSrcBufSize );
+                std::auto_ptr< sal_Char > pRowSrcName;
+                pRowSrcName.reset( new sal_Char[ nRowSrcBufSize ] );
+                pS->Read( pRowSrcName.get(), nRowSrcBufSize );
+                rec.sRowSource =  lclCreateOUString( pRowSrcName.get(), nRowSrcLen );
+                OSL_TRACE("*** *** *** RowSourceName -> %s ", rtl::OUStringToOString( rec.sRowSource, RTL_TEXTENCODING_UTF8 ).getStr() );
             }
 
             // seek to end of data
@@ -716,6 +765,13 @@ class ContainerRecReader
                 pControl->pDocSh = pContainerControl->pDocSh;
                 pContainerControl->ProcessControl( pControl, pS, rec );
             }
+            else if ( rec.nTypeIdent & 0x8000 )
+            {
+                // Skip ActiveX Controls we can't import
+                SotStorageStreamRef oStream = pContainerControl->getContainedControlsStream(); 
+                ULONG nStrmPos = oStream->Tell();
+                oStream->Seek( nStrmPos + rec.nSubStreamLen );
+            }  
             else
             {
                 DBG_ERROR("Terminating import, unexpected error");
@@ -736,6 +792,11 @@ class ContainerRecReader
     {
         sal_uInt8 aUnknown11[4];
         pS->Read(aUnknown11, sizeof(aUnknown11));
+        // discovered a dialog with value of 0xFF for aUnknown11 
+        // needed an extra 4 bytes to offset correctly  into the control
+        // records. Valid test or coincidence ?
+        if ( aUnknown11[1] == 0xFF )
+           pS->Read( aUnknown11, sizeof(aUnknown11));
         return true;
     }
 
@@ -810,176 +871,6 @@ class ContainerRecordReaderFac
 
 // ============================================================================
 
-void RBGroup::add(OCX_Control* pRB)
-{
-    // The tab index for the group is calculated as
-    // the lowest tab index found in the list of RadioButtons
-    if ( pRB->mnTabPos < mRBGroupPos )
-    {
-        mRBGroupPos = pRB->mnTabPos;
-        CtrlIterator aEnd = mpControls.end();
-        for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
-        {
-            (*aIter)->mnTabPos = mRBGroupPos;
-        }
-    }
-    mpControls.push_back( pRB );
-}
-
-struct SortGroupByTabPos
-{
-    bool operator()( const RBGroup* a, const RBGroup* b )
-    {
-        return a->tabPos() < b->tabPos();
-    }
-};
-
-RBGroupManager::RBGroupManager( String& defaultName ):mSDefaultName( defaultName ),
-    numRadioButtons(0)
-{
-    groupList.reserve( 8 ); // reserve far more than we expect
-}
-
-RBGroupManager::~RBGroupManager()
-{
-    for ( GroupIterator gIter=groupList.begin(); gIter!=groupList.end(); ++gIter )
-    {
-        delete( *gIter );
-    }
-}
-
-// Loose description of the method below ( I sure there is a better way to do
-// this )
-// In order to "fake" MS grouping behavior for OptionButtons the OptionButtons
-// in the same group need to have consecutive tab indices ( regardless of the
-// imported tab indices of the RadioButtons ). Additionally if two
-// groups of OptionButtons end up having all consecutive indices they
-// will be treated as a single group by OpenOffice. In this case
-// a dummy seperator control needs to be inserted between the groups.
-//
-// This method returns a new list "destinationList" containing the controls
-// passed in "sourceList" and the OptionButtons contained in the various
-// Groups maintained by this  class.
-// Controls are ordered in the destination list by tab index.
-// Each RadioButtonGroup has a tab index associated with it.
-// ( Tab index of a RadioGroup is determined as the tab index of the
-// OptionButton control with the lowest tab index in the group )
-
-
-void RBGroupManager::addRadioButton( OCX_OptionButton* pRButton )
-{
-    if ( pRButton )
-    {
-        OUString groupName = mSDefaultName;
-        if ( pRButton->nGroupNameLen )
-        {
-            groupName =
-                lclCreateOUString(pRButton->pGroupName,
-                    pRButton->nGroupNameLen);
-        }
-        ++numRadioButtons;
-        RBGroupHash::iterator iter = rbGroups.find( groupName );
-        if ( iter != rbGroups.end() )
-        {
-            iter->second->controls().push_back( pRButton );
-        }
-        else
-        {
-            RBGroup* newGroup = new RBGroup(pRButton->mnTabPos);
-            newGroup->controls().push_back( pRButton );
-            rbGroups[ groupName ] = newGroup;
-            groupList.push_back( newGroup );
-        }
-
-    }
-}
-
-CtrlList RBGroupManager::insertGroupsIntoControlList( const CtrlList& sourceList )
-{
-    ::std::sort( groupList.begin(), groupList.end(), SortGroupByTabPos() );
-    std::vector<OCX_Control*> destinationList;
-    if ( groupList.size() )
-    {
-        destinationList.reserve( sourceList.size() + numRadioButtons );
-
-        GroupIterator groupEnd = groupList.end();
-        CtrlIteratorConst sourceEnd = sourceList.end();
-
-        size_t prevGroupListSize = 0;
-
-        CtrlIteratorConst containees = sourceList.begin();
-        GroupIterator groupIter=groupList.begin();
-        while ( containees != sourceEnd ||
-                groupIter != groupEnd )
-        {
-            bool addGroupSeperator = false;
-            if ( containees != sourceEnd )
-            {
-                if ( groupIter != groupEnd )
-                {
-                    sal_Int16 groupTabPos = (*groupIter)->tabPos();
-                    if ( (*containees)->mnTabPos >= groupTabPos )
-                    {
-                       if ( !(destinationList.size() >=  prevGroupListSize ))
-                        {
-                            addGroupSeperator = true;
-                        }
-                        copyList( (*groupIter)->controls(), destinationList, addGroupSeperator );
-                        ++groupIter;
-
-                        prevGroupListSize = destinationList.size();
-                    }
-                }
-                destinationList.push_back(*containees);
-                ++containees;
-            }
-            else
-            {
-               if ( groupIter != groupEnd )
-               {
-                    if ( !(destinationList.size() >  prevGroupListSize ))
-                    {
-                        addGroupSeperator = true;
-                    }
-                    copyList( (*groupIter)->controls(), destinationList, addGroupSeperator );
-                    ++groupIter;
-                    prevGroupListSize = destinationList.size();
-                }
-            }
-        }
-    }
-    else
-    {
-        destinationList = sourceList;
-    }
-    return destinationList;
-
-}
-
-
-void RBGroupManager::addSeperator( std::vector< OCX_Control* >& dest )
-{
-    OCX_Control* seperator = new OCX_CommandButton;
-    seperator->SetInDialog(true);
-    seperator->sName = C2S("GroupSeperator");
-    dest.push_back( seperator );
-}
-
-void RBGroupManager::copyList( std::vector< OCX_Control* >& src,
-    std::vector< OCX_Control* >& dest,
-    bool addGroupSeperator )
-{
-    if ( addGroupSeperator )
-    {
-        addSeperator( dest );
-    }
-
-    for ( CtrlIterator rbIter = src.begin(); rbIter != src.end(); ++rbIter )
-    {
-        dest.push_back( *rbIter );
-    }
-}
-
 class OCX_UserFormLabel : public OCX_Label
 {
 public:
@@ -1146,6 +1037,9 @@ sal_Bool OCX_Control::Import(
 sal_Bool OCX_Control::Import(uno::Reference<container::XNameContainer> &rDialog
     )
 {
+    uno::Reference<beans::XPropertySet > xDlgProps( rDialog, uno::UNO_QUERY);
+
+    
     uno::Reference<lang::XMultiServiceFactory>
         xFactory(rDialog, uno::UNO_QUERY);
 
@@ -1158,11 +1052,15 @@ sal_Bool OCX_Control::Import(uno::Reference<container::XNameContainer> &rDialog
     if (!xModel.is())
         return sal_False;
 
+    sal_Bool bVBA = sal_False;
     /*  #147900# sometimes insertion of a control fails due to existing name,
         do not break entire form import then... */
     try
     {
         rDialog->insertByName(sName, uno::makeAny(xModel));
+        if ( xDlgProps.is() )
+            xDlgProps->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("VBAForm") ) ) >>= bVBA;
+
     }
     catch( uno::Exception& )
     {
@@ -1178,16 +1076,31 @@ sal_Bool OCX_Control::Import(uno::Reference<container::XNameContainer> &rDialog
 
     if (!Import(xPropSet))
         return sal_False;
-
+    
     uno::Any aTmp;
-    aTmp <<= sal_Int32((mnLeft * 2) / 100);
-    xPropSet->setPropertyValue(WW8_ASCII2STR("PositionX"), aTmp);
-    aTmp <<= sal_Int32((mnTop * 2) / 100);
-    xPropSet->setPropertyValue(WW8_ASCII2STR("PositionY"), aTmp);
-    aTmp <<= sal_Int32((nWidth * 2) / 100);
-    xPropSet->setPropertyValue(WW8_ASCII2STR("Width"), aTmp);
-    aTmp <<= sal_Int32((nHeight * 2) / 100);
-    xPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
+
+    if ( !bVBA  )
+    {
+        aTmp <<= sal_Int32((mnLeft * 2) / 100);
+        xPropSet->setPropertyValue(WW8_ASCII2STR("PositionX"), aTmp);
+        aTmp <<= sal_Int32((mnTop * 2) / 100);
+        xPropSet->setPropertyValue(WW8_ASCII2STR("PositionY"), aTmp);
+        aTmp <<= sal_Int32((nWidth * 2) / 100);
+        xPropSet->setPropertyValue(WW8_ASCII2STR("Width"), aTmp);
+        aTmp <<= sal_Int32((nHeight * 2) / 100);
+        xPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
+    }
+    else
+    {
+        aTmp <<= sal_Int32(mnLeft); // 100thmm
+        xPropSet->setPropertyValue(WW8_ASCII2STR("PositionX"), aTmp);
+        aTmp <<= sal_Int32(mnTop); //100th mm
+        xPropSet->setPropertyValue(WW8_ASCII2STR("PositionY"), aTmp);
+        aTmp <<= sal_Int32(nWidth); // 100thmm
+        xPropSet->setPropertyValue(WW8_ASCII2STR("Width"), aTmp);
+        aTmp <<= sal_Int32(nHeight); //100th mm
+        xPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
+    }
     if ( msToolTip.Len() > 0 )
         xPropSet->setPropertyValue(WW8_ASCII2STR("HelpText"), uno::Any(OUString(msToolTip)));
 
@@ -1402,6 +1315,12 @@ sal_Bool OCX_CommandButton::Import( com::sun::star::uno::Reference<
     rPropSet->setPropertyValue( WW8_ASCII2STR( "FocusOnClick" ), aTmp );
 
     aFontData.Import(rPropSet);
+
+    if ( sImageUrl.getLength() )
+    {
+        aTmp <<= sImageUrl;
+        rPropSet->setPropertyValue( WW8_ASCII2STR("ImageURL"), aTmp);
+    }
     return sal_True;
 }
 
@@ -1649,6 +1568,99 @@ sal_Bool OCX_ImageButton::Export(SvStorageRef &rObj,
     return WriteContents(xContents,rPropSet,rSize);
 }
 
+bool lcl_isNamedRange( const rtl::OUString& sAddress, uno::Reference< frame::XModel >& xModel, table::CellRangeAddress& aAddress )
+{
+    bool bRes = false;
+    const static rtl::OUString sNamedRanges( RTL_CONSTASCII_USTRINGPARAM("NamedRanges"));
+    uno::Reference< sheet::XCellRangeReferrer > xReferrer;
+    try
+    {
+        uno::Reference< beans::XPropertySet > xPropSet( xModel, uno::UNO_QUERY_THROW );
+        uno::Reference< container::XNameAccess > xNamed( xPropSet->getPropertyValue( sNamedRanges ), uno::UNO_QUERY_THROW );
+        xReferrer.set ( xNamed->getByName( sAddress ), uno::UNO_QUERY );
+    }
+    catch( uno::Exception& /*e*/ )
+    {
+        // do nothing
+    }
+    if ( xReferrer.is() )
+    {
+        uno::Reference< sheet::XCellRangeAddressable > xRangeAddressable( xReferrer->getReferredCells(), uno::UNO_QUERY );
+        if ( xRangeAddressable.is() )
+        {
+            aAddress = xRangeAddressable->getRangeAddress();
+            bRes = true;
+        }
+    }
+    return bRes;
+}
+
+void lcl_ApplyListSourceAndBindableStuff( uno::Reference< frame::XModel >& xModel, const uno::Reference< beans::XPropertySet >& rPropSet, const rtl::OUString& rsCtrlSource, const rtl::OUString& rsRowSource )
+{
+// XBindable etc.
+    uno::Reference< lang::XMultiServiceFactory > xFac;
+    if ( xModel.is() )
+        xFac.set( xModel, uno::UNO_QUERY );
+    uno::Reference< form::binding::XBindableValue > xBindable( rPropSet, uno::UNO_QUERY );
+    if (  xFac.is() && rsCtrlSource.getLength() && xBindable.is() )
+    {
+         
+         // OOo address structures
+         // RefCell - convert from XL
+         // pretend we converted the imported string address into the
+         // appropriate address structure
+         uno::Reference< beans::XPropertySet > xConvertor( xFac->createInstance( C2U( "com.sun.star.table.CellAddressConversion" )), uno::UNO_QUERY );
+         table::CellAddress aAddress;
+         if ( xConvertor.is() )
+         {
+             // we need this service to properly convert XL notation also
+             // Should be easy to extend
+             xConvertor->setPropertyValue( C2U( "XL_A1_Representation" ), uno::makeAny( rsCtrlSource ) );
+             xConvertor->getPropertyValue( C2U( "Address" ) ) >>= aAddress;    
+         }
+        
+         beans::NamedValue aArg1;
+         aArg1.Name = C2U("BoundCell");
+         aArg1.Value <<= aAddress;
+
+         uno::Sequence< uno::Any > aArgs(1);
+         aArgs[ 0 ]  <<= aArg1;
+
+         uno::Reference< form::binding::XValueBinding > xBinding( xFac->createInstanceWithArguments( C2U("com.sun.star.table.CellValueBinding" ), aArgs ), uno::UNO_QUERY );
+         xBindable->setValueBinding( xBinding );
+    }
+    uno::Reference< form::binding::XListEntrySink > xListEntrySink( rPropSet, uno::UNO_QUERY );
+    if (  xFac.is() && rsRowSource.getLength() && xListEntrySink.is() )
+    {
+         
+         // OOo address structures
+         // RefCell - convert from XL
+         // pretend we converted the imported string address into the
+         // appropriate address structure
+         uno::Reference< beans::XPropertySet > xConvertor( xFac->createInstance( C2U( "com.sun.star.table.CellRangeAddressConversion" )), uno::UNO_QUERY );
+         table::CellRangeAddress aAddress;
+         if ( xConvertor.is() )
+         {
+             if ( !lcl_isNamedRange( rsRowSource, xModel, aAddress ) )
+             {
+                 // we need this service to properly convert XL notation also
+                 // Should be easy to extend
+                 xConvertor->setPropertyValue( C2U( "XL_A1_Representation" ), uno::makeAny( rsRowSource ) );
+                 xConvertor->getPropertyValue( C2U( "Address" ) ) >>= aAddress;
+             }
+         }
+        
+         beans::NamedValue aArg1;
+         aArg1.Name = C2U("CellRange");
+         aArg1.Value <<= aAddress;
+
+         uno::Sequence< uno::Any > aArgs(1);
+         aArgs[ 0 ]  <<= aArg1;
+
+         uno::Reference< form::binding::XListEntrySource > xSource( xFac->createInstanceWithArguments( C2U("com.sun.star.table.CellRangeListSource" ), aArgs ), uno::UNO_QUERY );
+         xListEntrySink->setListEntrySource( xSource );
+    }
+}
 
 sal_Bool OCX_OptionButton::Import(com::sun::star::uno::Reference<
         com::sun::star::beans::XPropertySet> &rPropSet)
@@ -1681,12 +1693,51 @@ sal_Bool OCX_OptionButton::Import(com::sun::star::uno::Reference<
     aTmp <<= ImportSpecEffect( nSpecialEffect );
     rPropSet->setPropertyValue( WW8_ASCII2STR("VisualEffect"), aTmp);
 
-    if (pValue && !bSetInDialog)
+	if (pValue)
     {
         INT16 nTmp = pValue[0]-0x30;
         aTmp <<= nTmp;
-        rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultState"), aTmp);
-    }
+		if (!bSetInDialog)
+			rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultState"), aTmp);
+		else
+		{
+			// dialog ( but we might be using the form model )
+			if ( rPropSet->getPropertySetInfo()->hasPropertyByName( WW8_ASCII2STR("DefaultState") ) )
+				rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultState"), aTmp);
+			else
+				rPropSet->setPropertyValue( WW8_ASCII2STR("State"), aTmp);
+		}
+	}
+    // If this is a dialog control then we need to  set a groupname *always*
+    rtl::OUString sGroupName = lclCreateOUString( pGroupName, nGroupNameLen );
+    if ( GetInDialog() ) // Userform/Dialog
+    {
+        // By default groupnames are not set in Excel, it's not unusual to have
+        // a number of groups of radiobuttons located inside frame ( or other container
+        // controls ) where there is *no* specific groupname set for the radiobuttons.
+        // But... there is implicit grouping for radio buttons in seperate containers
+        // e.g. radio buttons in a frame are by default in the same group.
+        // Unfortunately in openoffice there are no containers below the dialog itself :-(
+        // To ensure correct grouping for imported radiobuttons either with no groupname
+        // or identical groupnames that are in separate containers we *must* ensure
+        // that a suitable groupname is applied. 
+        // Because controlNames are unique even across different containers we can use the
+        // controls container (e.g. parent) name as a prefix for a group name
+	rtl::OUString sParentName = msParentName;
+        sGroupName = sParentName.concat( C2U( ":" ) ).concat( sGroupName );
+    }
+    if ( sGroupName.getLength() == 0 )
+        sGroupName = rtl::OUString::createFromAscii("DefaultGroup");
+	OSL_TRACE("RadioButton %s has groupname %s", 
+		rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr(),  rtl::OUStringToOString( sGroupName, RTL_TEXTENCODING_UTF8 ).getStr() );
+        try
+        {
+            aTmp <<= sGroupName;
+            rPropSet->setPropertyValue( WW8_ASCII2STR("GroupName"), aTmp);
+        }
+        catch( uno::Exception& )
+        {
+        }
 
     if (pCaption)
     {
@@ -1698,6 +1749,14 @@ sal_Bool OCX_OptionButton::Import(com::sun::star::uno::Reference<
     aTmp <<= ::com::sun::star::style::VerticalAlignment_MIDDLE;
     rPropSet->setPropertyValue( WW8_ASCII2STR("VerticalAlign"), aTmp );
 
+	uno::Reference< frame::XModel > xModel ( pDocSh ? pDocSh->GetModel() : NULL );
+	lcl_ApplyListSourceAndBindableStuff( xModel, rPropSet, msCtrlSource, msRowSource );
+    if ( sImageUrl.getLength() )
+    {
+        aTmp <<= sImageUrl;
+        rPropSet->setPropertyValue( WW8_ASCII2STR("ImageURL"), aTmp);
+    }
+
     aFontData.Import(rPropSet);
     return sal_True;
 }
@@ -2322,8 +2381,9 @@ sal_Bool OCX_ToggleButton::Import(com::sun::star::uno::Reference<
     if (pValue)
     {
         INT16 nTmp=pValue[0]-0x30;
-        aTmp <<= nTmp == 1;
-        rPropSet->setPropertyValue( WW8_ASCII2STR("DefaultState"), aTmp);
+        //aTmp <<= nTmp == 1;
+        aTmp <<= nTmp;
+        rPropSet->setPropertyValue( WW8_ASCII2STR("State"), aTmp);
     }
 
     if (pCaption)
@@ -2333,6 +2393,12 @@ sal_Bool OCX_ToggleButton::Import(com::sun::star::uno::Reference<
     }
 
     aFontData.Import(rPropSet);
+	
+    if ( sImageUrl.getLength() )
+    {
+        aTmp <<= sImageUrl;
+        rPropSet->setPropertyValue( WW8_ASCII2STR("ImageURL"), aTmp);
+    }
     return sal_True;
 }
 
@@ -2588,6 +2654,8 @@ sal_Bool OCX_ComboBox::Import(com::sun::star::uno::Reference<
     rPropSet->setPropertyValue( WW8_ASCII2STR("MaxTextLen"), aTmp);
 
     aFontData.Import(rPropSet);
+	uno::Reference< frame::XModel > xModel ( pDocSh ? pDocSh->GetModel() : NULL );
+	lcl_ApplyListSourceAndBindableStuff( xModel, rPropSet, msCtrlSource, msRowSource );
     return sal_True;
 }
 
@@ -2807,7 +2875,8 @@ sal_Bool OCX_ListBox::Import(com::sun::star::uno::Reference<
 
     aTmp <<= ImportColor( nBorderColor );
     rPropSet->setPropertyValue( WW8_ASCII2STR("BorderColor"), aTmp);
-
+	uno::Reference< frame::XModel > xModel ( pDocSh ? pDocSh->GetModel() : NULL );
+	lcl_ApplyListSourceAndBindableStuff( xModel, rPropSet, msCtrlSource, msRowSource );
     aFontData.Import(rPropSet);
     return sal_True;
 }
@@ -3185,8 +3254,15 @@ sal_Bool OCX_ModernControl::Read(SvStorageStream *pS)
     {
         pS->Read(pPictureHeader,20);
         *pS >> nPictureLen;
-        pPicture = new sal_uInt8[nPictureLen];
-        pS->Read(pPicture,nPictureLen);
+		long imagePos = pS->Tell();
+		mxGrfObj = lcl_readGraphicObject( pS );
+		if( mxGrfObj.is() )
+		{
+			sImageUrl = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( GRAPHOBJ_URLPREFIX ) );
+			sImageUrl = sImageUrl + mxGrfObj->getUniqueID();
+		}
+		// make sure the stream position should be pointing after the image
+		pS->Seek( imagePos + nPictureLen );
     }
 
     return sal_True;
@@ -3276,8 +3352,15 @@ sal_Bool OCX_CommandButton::Read(SvStorageStream *pS)
     {
         pS->Read(pPictureHeader,20);
         *pS >> nPictureLen;
-        pPicture = new sal_uInt8[nPictureLen];
-        pS->Read(pPicture,nPictureLen);
+		long imagePos = pS->Tell();
+		mxGrfObj = lcl_readGraphicObject( pS );
+		if( mxGrfObj.is() )
+		{
+			sImageUrl = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( GRAPHOBJ_URLPREFIX ) );
+			sImageUrl = sImageUrl + mxGrfObj->getUniqueID();
+		}
+		// make sure the stream position should be pointing after the image
+		pS->Seek( imagePos + nPictureLen );
     }
 
     return sal_True;
@@ -3398,7 +3481,7 @@ OCX_ContainerControl::OCX_ContainerControl( SotStorageRef& parent,
             const ::rtl::OUString& sN,
             const uno::Reference< container::XNameContainer >  &rParent,
             OCX_Control* pParent ) :
-                OCX_Control(sN, pParent), rbGroupMgr( sName ), mxParent(rParent), nNoRecords(0), nTotalLen(0), containerType( STDCONTAINER )
+                OCX_Control(sN, pParent), mxParent(rParent), nNoRecords(0), nTotalLen(0), containerType( STDCONTAINER )
 {
 
     mContainerStorage = parent->OpenSotStorage(storageName,
@@ -3461,9 +3544,18 @@ OUString OCX_ContainerControl::createSubStreamName( const sal_uInt32& subStorage
     return buf.makeStringAndClear();
 }
 
-bool OCX_ContainerControl::createFromContainerRecord( const ContainerRecord& record, OCX_Control*& pControl )
+
+bool OCX_ContainerControl::createFromContainerRecord( ContainerRecord& record, OCX_Control*& pControl )
 {
     pControl = NULL;
+    if (  record.nTypeIdent & 0x8000 )
+    {
+        std::hash_map<sal_uInt16, sal_uInt16>::iterator it = mActiveXIDMap.find( record.nTypeIdent );
+        if ( it == mActiveXIDMap.end() )
+            return false;
+        // replace the generated id with our hardcoded one
+        record.nTypeIdent = it->second; 
+    }
     switch ( record.nTypeIdent)
         {
             case CMDBUTTON:
@@ -3571,8 +3663,7 @@ void OCX_ContainerControl::ProcessControl(OCX_Control* pControl,SvStorageStream*
     SotStorageStreamRef oStream = mContainedControlsStream;
 
     // can insert into OO Dialog (e.g is this a supported dialog control)??
-    if ( rec.nTypeIdent == SPINBUTTON ||
-        rec.nTypeIdent == TABSTRIP)
+    if ( rec.nTypeIdent == TABSTRIP )
     {
         // skip the record in the stream, discard the control
         oStream->SeekRel( rec.nSubStreamLen );
@@ -3582,15 +3673,27 @@ void OCX_ContainerControl::ProcessControl(OCX_Control* pControl,SvStorageStream*
     {
         // A container control needs to read the f stream in
         // the folder ( substorage ) associated with this control
-        if (  rec.nTypeIdent ==  FRAME ||
-            rec.nTypeIdent ==  MULTIPAGE||
-            rec.nTypeIdent ==  PAGE )
+        switch ( rec.nTypeIdent )
         {
-            OCX_ContainerControl* pContainer =
-               static_cast< OCX_ContainerControl* >( pControl );
-            oStream = pContainer->getContainerStream();
+            case FRAME:
+            case MULTIPAGE:
+            case PAGE:
+                {
+                    OCX_ContainerControl* pContainer =
+                        static_cast< OCX_ContainerControl* >( pControl );
+                    oStream = pContainer->getContainerStream();
+                    break;
+                }
+            case LISTBOX:
+            case OPTIONBUTTON:
+            case COMBOBOX:
+			case SPINBUTTON:
+			case SCROLLBAR:
+                {
+                    pControl->msCtrlSource = rec.sCtrlSource;
+                    pControl->msRowSource = rec.sRowSource;
+                }
         }
-
         pControl->sName = rec.cName;
         pControl->msToolTip = rec.controlTip;
         // Position of controls is relative to the container
@@ -3610,6 +3713,7 @@ void OCX_ContainerControl::ProcessControl(OCX_Control* pControl,SvStorageStream*
             // applied to all containees
             pControl->mnStep = mnStep;
         }
+        pControl->msParentName = sName;
 
         // #117490# DR: container records provide size of substream, use it here...
 
@@ -3620,17 +3724,7 @@ void OCX_ContainerControl::ProcessControl(OCX_Control* pControl,SvStorageStream*
         // set stream to position behind substream of this control
         oStream->Seek( nStrmPos + rec.nSubStreamLen );
 
-        //need to fake grouping behaviour for radio ( option ) buttons
-        if ( rec.nTypeIdent == OPTIONBUTTON )
-        {
-            OCX_OptionButton* pRButton =
-                static_cast< OCX_OptionButton*>(pControl);
-            rbGroupMgr.addRadioButton( pRButton );
-        }
-        else
-        {
-            mpControls.push_back( pControl );
-        }
+        mpControls.push_back( pControl );
     }
 }
 
@@ -3653,7 +3747,6 @@ sal_Bool OCX_ContainerControl::Read(SvStorageStream *pS)
     // this ensures that the default tab index created by Star/Open office
     // reflects the "flattened" ms tab order.
     ::std::sort( mpControls.begin(), mpControls.end(), SortOrderByTabPos() );
-    mpControls = rbGroupMgr.insertGroupsIntoControlList( mpControls );
     return true;
 }
 
@@ -3671,7 +3764,8 @@ OCX_MultiPage::OCX_MultiPage( SotStorageRef& parent,
         nScrollWidth(0), nScrollHeight(0), nIconLen(0), pIcon(0), nPictureLen(0),
         pPicture(0)
 {
-    msDialogType = C2U("NotSupported");
+    //msDialogType = C2U("NotSupported");
+    msDialogType = C2U("com.sun.star.awt.UnoMultiPageModel");
     mnForeColor = 0x80000012L,
     mnBackColor = 0x8000000FL;
     bSetInDialog = true;// UserForm control only
@@ -3735,7 +3829,6 @@ sal_Bool OCX_MultiPage::Read(SvStorageStream *pS)
 sal_Bool OCX_MultiPage::Import(com::sun::star::uno::Reference<
     com::sun::star::beans::XPropertySet> &rPropSet)
 {
-    // Calls import on contained controls
     OCX_ContainerControl::Import( rPropSet );
     return sal_True;
 }
@@ -3756,6 +3849,43 @@ sal_Bool OCX_MultiPage::Import(com::sun::star::uno::Reference<
 
     if ( xPropSet.is() )
     {
+        uno::Reference<lang::XMultiServiceFactory>
+            xFactory(rDialog, uno::UNO_QUERY);
+	OSL_TRACE("** MultiPage creating control %s", rtl::OUStringToOString( msDialogType, RTL_TEXTENCODING_UTF8 ).getStr() );
+	uno::Reference<uno::XInterface> xCreate = xFactory->createInstance(msDialogType);
+	if (!xCreate.is())
+		return sal_False;
+
+	uno::Reference<awt::XControlModel> xModel(xCreate, uno::UNO_QUERY);
+	if (!xModel.is())
+		return sal_False;
+
+        try
+        {
+		// we should just call MultiPage::Import( XPropertySet )
+    		OSL_TRACE("********* MULTIPAGE cName %s", rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr() );
+		uno::Any aTmp(&sName,getCppuType((OUString *)0));
+		uno::Reference<beans::XPropertySet> xPrps(xModel, uno::UNO_QUERY);
+		xPrps->setPropertyValue( WW8_ASCII2STR("Name"), aTmp );
+		aTmp = uno::makeAny( mnCurrentPageStep );
+		xPrps->setPropertyValue( WW8_ASCII2STR("ProgressValueMax"), aTmp );
+		// default current page to 0 ( #FIXME, we need to read this value )
+		aTmp = uno::makeAny( sal_Int32(0) );
+		xPrps->setPropertyValue( WW8_ASCII2STR("ProgressValue"), aTmp );
+    		OSL_TRACE("********* MULTIPAGE vomitted out properties");
+
+    // Calls import on contained controls
+            rDialog->insertByName(sName, uno::makeAny(xModel));
+            OSL_TRACE("*** inserted ***");
+        }
+        catch( uno::Exception& )
+        {
+            DBG_ERRORFILE(
+                ByteString( "OCX_Control::Import - cannot insert control \"" ).
+                Append( ByteString( sName, RTL_TEXTENCODING_UTF8 ) ).
+                Append( '"' ).GetBuffer() );
+        }
+
         // Calls import on contained pages

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list