summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/inc/filter/msfilter/escherex.hxx21
-rw-r--r--filter/inc/filter/msfilter/msocximex.hxx82
-rw-r--r--filter/inc/filter/msfilter/svxmsbas.hxx18
-rw-r--r--filter/source/msfilter/eschesdo.cxx13
-rw-r--r--filter/source/msfilter/makefile.mk2
-rw-r--r--filter/source/msfilter/msocximex.cxx945
-rw-r--r--filter/source/msfilter/msoleexp.cxx5
-rw-r--r--filter/source/msfilter/msvbasic.cxx812
-rw-r--r--filter/source/msfilter/msvbasic.hxx11
-rw-r--r--filter/source/msfilter/svxmsbas.cxx113
-rwxr-xr-x[-rw-r--r--]oox/inc/oox/ole/vbacontrol.hxx2
-rwxr-xr-x[-rw-r--r--]oox/source/ole/vbacontrol.cxx5
-rwxr-xr-x[-rw-r--r--]oox/source/ole/vbaproject.cxx2
13 files changed, 1574 insertions, 457 deletions
diff --git a/filter/inc/filter/msfilter/escherex.hxx b/filter/inc/filter/msfilter/escherex.hxx
index 51058e2eabd8..6bf0e8b9c200 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 a106b40d2852..ef82cfe6d35a 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;
diff --git a/filter/inc/filter/msfilter/svxmsbas.hxx b/filter/inc/filter/msfilter/svxmsbas.hxx
index 716c6788989c..2fdf935821c6 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 0844f153dd4d..d34945cb896b 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 7780529b5580..c59a1262b8e2 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 248affc540c1..37575c656d20 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,6 +73,21 @@
#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))
@@ -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,127 +131,49 @@ 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;
-}
-
-// 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< graphic::XGraphicObject> lcl_readGraphicObject( SotStorageStream *pS )
{
- uno::Reference < embed::XStorage > xStor;
- if (pDocSh)
+ uno::Reference< graphic::XGraphicObject > xGrfObj;
+ uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
+ if( xServiceManager.is() )
{
- xStor = pDocSh->GetStorage();
- if( xStor.is() )
+ try
{
- 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< 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() )
+ uno::Reference< io::XInputStream > xStream( new utl::OInputStreamWrapper( *pS ) );
+ if( xStream.is() )
{
- xTransact->commit();
+ 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 false;
- }
-
}
- else
+ catch( uno::Exception& )
{
- // no storage something wrong
- return false;
}
}
- else
- {
- //No doc shell
- return false;
- }
- return true;
+ return xGrfObj;
}
+
long WriteAlign(SvStorageStream *pS, int nAmount)
{
if (long nAlign = pS->Tell() % 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& )
{
@@ -1180,14 +1078,29 @@ sal_Bool OCX_Control::Import(uno::Reference<container::XNameContainer> &rDialog
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
return OCX_ContainerControl::Import( xPropSet );
}
@@ -4042,8 +4172,7 @@ OCX_UserForm::OCX_UserForm( SotStorageRef& parent,
nKeepScrollBarsVisible(3), nCycle(0), nBorderStyle(0), nSpecialEffect(0),
nPicture(0), nPictureAlignment(2), nPictureSizeMode(0),
bPictureTiling(FALSE), nAccelerator(0), nIcon(0), pCaption(0),
- nScrollWidth(0), nScrollHeight(0), nScrollLeft(0), nScrollTop(0), nIconLen(0), pIcon(0), nPictureLen(0),
- pPicture(0)
+ nScrollWidth(0), nScrollHeight(0), nScrollLeft(0), nScrollTop(0), nIconLen(0), pIcon(0), nPictureLen(0)
{
mnForeColor = 0x80000012;
mnBackColor = 0x8000000F;
@@ -4173,16 +4302,7 @@ sal_Bool OCX_UserForm::Read(SvStorageStream *pS)
pS->Read(pIcon,nIconLen);
}
- if (nPicture)
- {
- pS->Read(pPictureHeader,20);
- *pS >> nPictureLen;
- pPicture = new sal_uInt8[nPictureLen];
- pS->Read(pPicture,nPictureLen);
- }
-
ReadAlign( pS, pS->Tell() - nStart, 4);
-
if (pBlockFlags[2] & 0x10)
{
//Font Stuff..
@@ -4191,6 +4311,21 @@ sal_Bool OCX_UserForm::Read(SvStorageStream *pS)
*pS >> nFontLen;
pS->SeekRel(nFontLen);
}
+ if (nPicture)
+ {
+ pS->Read(pPictureHeader,20);
+ *pS >> nPictureLen;
+ long imagePos = pS->Tell();
+ // great embedded object
+ 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 );
+ }
sal_Int16 numTrailingRecs = 0;
*pS >> numTrailingRecs;
@@ -4199,10 +4334,14 @@ sal_Bool OCX_UserForm::Read(SvStorageStream *pS)
// ( unknown what these trailing records are for)
if ( numTrailingRecs )
{
- for ( ; numTrailingRecs ; --numTrailingRecs )
+ for ( sal_Int16 i = 0 ; numTrailingRecs ; --numTrailingRecs, ++i )
{
- OCX_Control skip(C2S("dummy")) ;
- skip.Read( pS );
+ sal_uInt16 nTypeID = 0;
+ if ( lcl_handleActiveXControl( pS, nTypeID ) )
+ {
+ if ( nTypeID & 0x8000 ) // valid ActiveXID
+ mActiveXIDMap[ ( i | 0x8000 ) ] = nTypeID;
+ }
}
}
return OCX_ContainerControl::Read( pS );
@@ -4213,6 +4352,8 @@ sal_Bool OCX_UserForm::Import(
{
uno::Reference<beans::XPropertySet>
xDialogPropSet(mxParent, uno::UNO_QUERY);
+ if ( !xDialogPropSet.is() )
+ return sal_False;
uno::Any aTmp(&sName,getCppuType((OUString *)0));
xDialogPropSet->setPropertyValue(
OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), aTmp);
@@ -4220,22 +4361,55 @@ sal_Bool OCX_UserForm::Import(
OUString(RTL_CONSTASCII_USTRINGPARAM("Title")), aTmp);
aTmp <<= ImportColor(mnBackColor);
xDialogPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+ sal_Bool bVBA = sal_False;
+ // Ok we are importing xls but maybe we aren't in VBA mode
+ // if we are not in VBA mode then we should import sizes etc. ( as before )
+ try
+ {
+ xDialogPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("VBAForm") ) ) >>= bVBA;
+ }
+ catch( uno::Exception& e )
+ {
+ }
+ if ( !bVBA )
+ {
+ aTmp <<= sal_Int32((nWidth * 2) / 100);
+ xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Width"), aTmp);
+ aTmp <<= sal_Int32((nHeight * 2) / 100);
+ xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
+ }
+ else
+ {
+ aTmp <<= sal_Int32( nWidth + 160 ); // 100thmm
+ xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Width"), aTmp);
+ aTmp <<= sal_Int32(nHeight + 662 - 714); //100th mm
+ xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
+ }
- aTmp <<= sal_Int32((nWidth * 2) / 100);
- xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Width"), aTmp);
- aTmp <<= sal_Int32((nHeight * 2) / 100);
- xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
uno::Reference<beans::XPropertySet> xPropSet( mxParent, uno::UNO_QUERY );
OCX_ContainerControl::Import( xPropSet );
uno::Reference<io::XInputStreamProvider> xSource =
- xmlscript::exportDialogModel(mxParent, mxCtx);
+ xmlscript::exportDialogModel(mxParent, mxCtx, pDocSh->GetModel() );
uno::Any aSourceAny(uno::makeAny(xSource));
if (rLib->hasByName(sName))
rLib->replaceByName(sName, aSourceAny);
else
rLib->insertByName(sName, aSourceAny);
+
+ if ( sImageUrl.getLength() )
+ {
+ aTmp <<= sImageUrl;
+ try
+ {
+ xDialogPropSet->setPropertyValue( WW8_ASCII2STR("ImageURL"), aTmp);
+ }
+ catch( uno::Exception& )
+ {
+ OSL_TRACE("OCX_UserForm::Import, Image fails to import");
+ }
+ }
return sal_True;
}
@@ -4761,11 +4935,14 @@ sal_Bool OCX_CheckBox::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
+ rPropSet->setPropertyValue( WW8_ASCII2STR("State"), aTmp);
}
if (pCaption)
@@ -5272,12 +5449,6 @@ sal_Bool OCX_TabStrip::ReadFontData(SotStorageStream *pS)
sal_Bool OCX_Image::Read(SotStorageStream *pS)
{
- if ( !bSetInDialog )
- {
- // preserve the present behavior at the moment.
- // only import image control for UserForms
- return sal_False;
- }
ULONG nStart = pS->Tell();
*pS >> nIdentifier;
DBG_ASSERT(nStandardId==nIdentifier,
@@ -5368,16 +5539,14 @@ sal_Bool OCX_Image::Read(SotStorageStream *pS)
long imagePos = pS->Tell();
- pS->Seek( imagePos );
-
- sImageUrl = C2U("vnd.sun.star.expand:${$BRAND_BASE_DIR/program/") + C2U( SAL_CONFIGFILE( "bootstrap" ) ) + C2U("::UserInstallation}/user/temp/") + sName;
-
- sal_uInt8* pImage = new sal_uInt8[ nImageLen ];
- pS->Read(pImage, nImageLen);
- bool result = storePictureInFileSystem( sImageUrl, pImage, nImageLen );
- OUString pictName = sImageUrl.copy( sImageUrl.lastIndexOf('/') + 1 );
- result = storePictureInDoc( pDocSh, pictName, pImage, nImageLen );
- delete [] pImage;
+ 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 + nImageLen );
}
return sal_True;
}
@@ -5545,7 +5714,7 @@ OCX_SpinButton::OCX_SpinButton() :
mbPropThumb( true )
{
msFormType = C2U("com.sun.star.form.component.SpinButton");
- msDialogType = C2U("com.sun.star.awt.UnoControlSpinButtonModel");
+ msDialogType = C2U("com.sun.star.form.component.SpinButton");
mnBackColor = 0x8000000F;
mnForeColor = 0x80000012;
}
@@ -5582,8 +5751,8 @@ sal_Bool OCX_SpinButton::Read( SvStorageStream *pS )
if( mnBlockFlags & 0x00000080 ) rStrm >> mnValue;
if( mnBlockFlags & 0x00000100 ) rStrm.SeekRel( 4 ); // unknown
if( mnBlockFlags & 0x00000200 ) rStrm.SeekRel( 4 ); // unknown
- if( mnBlockFlags & 0x00000400 ) rStrm.SeekRel( 4 ); // unknown
- if( mnBlockFlags & 0x00000800 ) rStrm >> mnSmallStep;
+ if( mnBlockFlags & 0x00000400 ) rStrm >> mnSmallStep;
+ if( mnBlockFlags & 0x00000800 ) rStrm.SeekRel( 4 ); // unknown
if( mnBlockFlags & 0x00001000 ) rStrm >> mnPageStep;
if( mnBlockFlags & 0x00002000 ) rStrm >> mnOrient;
if( mnBlockFlags & 0x00004000 )
@@ -5668,6 +5837,9 @@ sal_Bool OCX_SpinButton::Import(com::sun::star::uno::Reference<
aTmp <<= sal_Int16( 0 );
rPropSet->setPropertyValue( WW8_ASCII2STR("Border"), aTmp);
+ uno::Reference< frame::XModel > xModel ( pDocSh ? pDocSh->GetModel() : NULL );
+ lcl_ApplyListSourceAndBindableStuff( xModel, rPropSet, msCtrlSource, msRowSource );
+
return sal_True;
}
@@ -5835,7 +6007,7 @@ OCX_ScrollBar::OCX_ScrollBar()
sName = OUString( RTL_CONSTASCII_USTRINGPARAM( "ScrollBar" ) );
mnMax = 32767;
msFormType = C2U("com.sun.star.form.component.ScrollBar");
- msDialogType = C2U("com.sun.star.awt.UnoControlScrollBarModel");
+ msDialogType = C2U("com.sun.star.form.component.ScrollBar");
}
@@ -5901,6 +6073,9 @@ sal_Bool OCX_ScrollBar::Import(com::sun::star::uno::Reference<
aTmp <<= sal_Int16( 0 );
rPropSet->setPropertyValue( WW8_ASCII2STR("Border"), aTmp);
+ uno::Reference< frame::XModel > xModel ( pDocSh ? pDocSh->GetModel() : NULL );
+ lcl_ApplyListSourceAndBindableStuff( xModel, rPropSet, msCtrlSource, msRowSource );
+
return sal_True;
}
diff --git a/filter/source/msfilter/msoleexp.cxx b/filter/source/msfilter/msoleexp.cxx
index 52214ea443c8..a3fa45784977 100644
--- a/filter/source/msfilter/msoleexp.cxx
+++ b/filter/source/msfilter/msoleexp.cxx
@@ -220,7 +220,12 @@ void SvxMSExportOLEObjects::ExportOLEObject( svt::EmbeddedObjectRef& rObj, SvSto
aSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
aSeq[1].Value <<= ::rtl::OUString( pExpFilter->GetName() );
uno::Reference < frame::XStorable > xStor( rObj->getComponent(), uno::UNO_QUERY );
+ try
+ {
xStor->storeToURL( ::rtl::OUString::createFromAscii( "private:stream" ), aSeq );
+ }
+ catch( uno::Exception& ) {} // #TODO really handle exceptions - interactionalhandler etc. ?
+
SotStorageRef xOLEStor = new SotStorage( pStream, TRUE );
xOLEStor->CopyTo( &rDestStg );
rDestStg.Commit();
diff --git a/filter/source/msfilter/msvbasic.cxx b/filter/source/msfilter/msvbasic.cxx
index fa954d1177b2..16d57db30175 100644
--- a/filter/source/msfilter/msvbasic.cxx
+++ b/filter/source/msfilter/msvbasic.cxx
@@ -38,11 +38,804 @@
#include <osl/endian.h>
#include <rtl/tencinfo.h> //rtl_getTextEncodingFromWindowsCodePage
#include "msvbasic.hxx"
+#include <memory>
+#include <rtl/ustrbuf.hxx>
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/shared_array.hpp>
+#include <svtools/filterutils.hxx>
#include <com/sun/star/script/ModuleType.hpp>
+#include <fstream>
using namespace ::com::sun::star::script;
+namespace MSLZSS {
+
+static unsigned int getShift( sal_uInt32 nPos )
+{
+ if (nPos <= 0x80) {
+ if (nPos <= 0x20)
+ return (nPos <= 0x10) ? 12 : 11;
+ else
+ return (nPos <= 0x40) ? 10 : 9;
+ } else {
+ if (nPos <= 0x200)
+ return (nPos <= 0x100) ? 8 : 7;
+ else if (nPos <= 0x800)
+ return (nPos <= 0x400) ? 6 : 5;
+ else
+ return 4;
+ }
+}
+
+SvMemoryStream *decompressAsStream( SvStream *pStream, sal_uInt32 nOffset, sal_uInt32 *pCompressedLength = NULL, sal_uInt32 *pLength = NULL )
+{
+ SvMemoryStream *pResult;
+ const sal_Int32 nWINDOWLEN = 4096;
+ pResult = new SvMemoryStream();
+
+ sal_uInt8 nLeadbyte;
+ unsigned int nPos = 0;
+ int nLen, nDistance, nShift, nClean=1;
+ sal_uInt8 aHistory[ nWINDOWLEN ];
+
+ pStream->Seek( nOffset + 3 );
+
+ while( pStream->Read( &nLeadbyte, 1 ) )
+ {
+ for(int nMask=0x01; nMask < 0x100; nMask = nMask<<1)
+ {
+ // we see if the leadbyte has flagged this location as a dataunit
+ // which is actually a token which must be looked up in the history
+ if( nLeadbyte & nMask )
+ {
+ sal_uInt16 nToken;
+
+ *pStream >> nToken;
+
+ if (nClean == 0)
+ nClean=1;
+
+ //For some reason the division of the token into the length
+ //field of the data to be inserted, and the distance back into
+ //the history differs depending on how full the history is
+ nShift = getShift( nPos % nWINDOWLEN );
+
+ nLen = (nToken & ((1<<nShift) - 1)) + 3;
+ nDistance = nToken >> nShift;
+
+ //read the len of data from the history, wrapping around the
+ //nWINDOWLEN boundary if necessary data read from the history
+ //is also copied into the recent part of the history as well.
+ for (int i = 0; i < nLen; i++)
+ {
+ unsigned char c;
+ c = aHistory[(nPos-nDistance-1) % nWINDOWLEN];
+ aHistory[nPos % nWINDOWLEN] = c;
+ nPos++;
+ }
+ }
+ else
+ {
+ // special boundary case code, not guarantueed to be correct
+ // seems to work though, there is something wrong with the
+ // compression scheme (or maybe a feature) where when the data
+ // ends on a nWINDOWLEN boundary and the excess bytes in the 8
+ // dataunit list are discarded, and not interpreted as tokens
+ // or normal data.
+ if ((nPos != 0) && ((nPos % nWINDOWLEN) == 0) && (nClean))
+ {
+ pStream->SeekRel(2);
+ nClean=0;
+ pResult->Write( aHistory, nWINDOWLEN );
+ break;
+ }
+ //This is the normal case for when the data unit is not a
+ //token to be looked up, but instead some normal data which
+ //can be output, and placed in the history.
+ if (pStream->Read(&aHistory[nPos % nWINDOWLEN],1))
+ nPos++;
+
+ if (nClean == 0)
+ nClean=1;
+ }
+ }
+ }
+ if (nPos % nWINDOWLEN)
+ pResult->Write( aHistory, nPos % nWINDOWLEN );
+ pResult->Flush();
+
+ if( pCompressedLength )
+ *pCompressedLength = nPos;
+
+ if( pLength )
+ *pLength = pResult->Tell();
+
+ pResult->Seek( 0 );
+
+ return pResult;
+}
+
+} //MSZSS
+
+// also _VBA_PROJECT_VDPI can be used to create a usable
+// ( and much smaller ) "_VBA_PROJECT" stream
+
+// _VBA_PROJECT Stream Version Dependant Project Information
+// _VBA_PROJECT Stream Version Dependant Project Information
+
+class _VBA_PROJECT_VDPI
+{
+public:
+sal_Int16 Reserved1;
+sal_Int16 Version;
+sal_Int8 Reserved2;
+sal_Int16 Reserved3;
+boost::scoped_array< sal_uInt8 > PerformanceCache;
+sal_Int32 PerformanceCacheSize;
+_VBA_PROJECT_VDPI(): Reserved1( 0x61CC), Version( 0xFFFF ), Reserved2(0x0), Reserved3(0x0), PerformanceCacheSize(0) {}
+~_VBA_PROJECT_VDPI()
+{
+ PerformanceCacheSize = 0;
+}
+void read(){}
+void write( SvStream* pStream )
+{
+ *pStream << Reserved1 << Version << Reserved2 << Reserved3;
+ if ( PerformanceCacheSize )
+ {
+ PerformanceCache.reset( new sal_uInt8[ PerformanceCacheSize ] );
+ pStream->Read( PerformanceCache.get(), PerformanceCacheSize );
+ }
+}
+};
+
+class ProjectSysKindRecord
+{
+public:
+sal_Int16 Id;
+sal_Int32 Size;
+sal_Int32 SysKind;
+ProjectSysKindRecord(): Id(0x1), Size(0x4), SysKind( 0x1 ) {}
+void read( SvStream* pStream )
+{
+ *pStream >> Id >> Size >> SysKind;
+}
+};
+
+class ProjectLcidRecord
+{
+public:
+sal_Int16 Id;
+sal_Int32 Size;
+sal_Int32 Lcid;
+
+ProjectLcidRecord() : Id( 0x2 ), Size( 0x4 ), Lcid( 0x409 ) {}
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectLcidRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> Size >> Lcid;
+}
+};
+
+class ProjectLcidInvokeRecord
+{
+sal_Int16 Id;
+sal_Int32 Size;
+sal_Int32 LcidInvoke;
+public:
+ProjectLcidInvokeRecord() : Id( 0x14 ), Size( 0x4 ), LcidInvoke( 0x409 ) {}
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectLcidInvokeRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> Size >> LcidInvoke;
+}
+};
+
+class ProjectCodePageRecord
+{
+sal_Int16 Id;
+sal_Int32 Size;
+sal_Int16 CodePage;
+public:
+// #FIXME get a better default for the CodePage
+ProjectCodePageRecord() : Id( 0x03 ), Size( 0x2 ), CodePage( 0x0 ) {}
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectCodePageRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> Size >> CodePage;
+}
+};
+class ProjectNameRecord
+{
+public:
+sal_Int16 Id;
+sal_Int32 SizeOfProjectName;
+rtl::OUString ProjectName;
+ProjectNameRecord() : Id( 0x04 ), SizeOfProjectName( 0x0 ){}
+~ProjectNameRecord()
+{
+}
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectNameRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> SizeOfProjectName;
+
+ if ( SizeOfProjectName )
+ {
+ boost::scoped_array< sal_uInt8 > pProjectName( new sal_uInt8[ SizeOfProjectName ] );
+ OSL_TRACE("ProjectNameRecord about to read name from [0x%x], size %d", pStream->Tell(), SizeOfProjectName );
+ pStream->Read( pProjectName.get(), SizeOfProjectName );
+ ProjectName = svt::BinFilterUtils::CreateOUStringFromStringArray( reinterpret_cast< const char* >( pProjectName.get() ), SizeOfProjectName );
+ }
+}
+};
+
+class ProjectDocStringRecord
+{
+public:
+sal_Int16 Id;
+sal_Int32 SizeOfDocString;
+sal_Int16 Reserved;
+sal_Int32 SizeOfDocStringUnicode;
+rtl::OUString DocString;
+rtl::OUString DocStringUnicode;
+
+ProjectDocStringRecord() : Id( 0x5 ), SizeOfDocString( 0x0 ), Reserved( 0x0 ), SizeOfDocStringUnicode( 0 ){}
+
+~ProjectDocStringRecord()
+{
+}
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectDocStringRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> SizeOfDocString;
+
+
+ boost::scoped_array< sal_uInt8 > pDocString( new sal_uInt8[ SizeOfDocString ] );
+ pStream->Read( pDocString.get(), SizeOfDocString );
+
+ DocString = svt::BinFilterUtils::CreateOUStringFromStringArray( reinterpret_cast< const char* >( pDocString.get() ), SizeOfDocString );
+
+ *pStream >> Reserved >> SizeOfDocStringUnicode;
+
+ boost::scoped_array< sal_uInt8 > pDocStringUnicode( new sal_uInt8[ SizeOfDocStringUnicode ] );
+
+ pStream->Read( pDocStringUnicode.get(), SizeOfDocStringUnicode );
+ DocStringUnicode = svt::BinFilterUtils::CreateOUStringFromUniStringArray( reinterpret_cast< const char* >( pDocStringUnicode.get() ), SizeOfDocString );
+
+}
+
+};
+
+class ProjectHelpFilePath
+{
+public:
+sal_Int16 Id;
+sal_Int32 SizeOfHelpFile1;
+boost::scoped_array< sal_uInt8 > HelpFile1;
+sal_Int16 Reserved;
+sal_Int32 SizeOfHelpFile2;
+boost::scoped_array< sal_uInt8 > HelpFile2;
+
+ProjectHelpFilePath() : Id( 0x06 ), SizeOfHelpFile1(0), Reserved(0x0), SizeOfHelpFile2(0) {}
+~ProjectHelpFilePath()
+{
+}
+
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectHelpFilePath [0x%x]", pStream->Tell() );
+ *pStream >> Id >> SizeOfHelpFile1;
+
+ HelpFile1.reset( new sal_uInt8[ SizeOfHelpFile1 ] );
+ pStream->Read( HelpFile1.get(), SizeOfHelpFile1 );
+
+ *pStream >> Reserved >> SizeOfHelpFile2;
+
+ HelpFile2.reset( new sal_uInt8[ SizeOfHelpFile2 ] );
+ pStream->Read( HelpFile2.get(), SizeOfHelpFile2 );
+
+}
+};
+
+class ProjectHelpContextRecord
+{
+public:
+sal_Int16 Id;
+sal_Int32 Size;
+sal_Int32 HelpContext;
+
+ProjectHelpContextRecord() : Id( 0x7 ), Size( 0x4 ), HelpContext( 0 ) {}
+void read( SvStream* pStream )
+{
+
+ OSL_TRACE("ProjectHelpContextRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> Size >> HelpContext;
+}
+
+};
+
+class ProjectLibFlagsRecord
+{
+sal_Int16 Id;
+sal_Int32 Size;
+sal_Int32 ProjectLibFlags;
+
+public:
+ProjectLibFlagsRecord() : Id( 0x8 ), Size( 0x4 ), ProjectLibFlags( 0x0 ) {}
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectLibFlagsRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> Size >> ProjectLibFlags;
+}
+};
+
+class ProjectVersionRecord
+{
+public:
+sal_Int16 Id;
+sal_Int32 Reserved;
+sal_Int32 VersionMajor;
+sal_Int16 VersionMinor;
+ProjectVersionRecord() : Id( 0x9 ), Reserved( 0x4 ), VersionMajor( 0x1 ), VersionMinor( 0 ) {}
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectVersionRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> Reserved >> VersionMajor >> VersionMinor;
+}
+};
+
+class ProjectConstantsRecord
+{
+sal_Int16 Id;
+sal_Int32 SizeOfConstants;
+boost::scoped_array< sal_uInt8 > Constants;
+sal_Int16 Reserved;
+sal_Int32 SizeOfConstantsUnicode;
+boost::scoped_array< sal_uInt8 > ConstantsUnicode;
+public:
+ProjectConstantsRecord() : Id( 0xC ), SizeOfConstants( 0 ), Constants( 0 ), Reserved( 0x3C ), SizeOfConstantsUnicode( 0 ), ConstantsUnicode(0) {}
+
+~ProjectConstantsRecord()
+{
+}
+
+void read( SvStream* pStream )
+{
+ OSL_TRACE("ProjectConstantsRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> SizeOfConstants;
+ Constants.reset( new sal_uInt8[ SizeOfConstants ] );
+
+ pStream->Read( Constants.get(), SizeOfConstants );
+
+ *pStream >> Reserved;
+
+ *pStream >> SizeOfConstantsUnicode;
+
+ ConstantsUnicode.reset( new sal_uInt8[ SizeOfConstantsUnicode ] );
+ pStream->Read( ConstantsUnicode.get(), SizeOfConstantsUnicode );
+}
+
+};
+
+class ReferenceNameRecord
+{
+public:
+sal_Int16 Id;
+sal_Int32 SizeOfName;
+rtl::OUString Name;
+sal_Int16 Reserved;
+sal_Int32 SizeOfNameUnicode;
+rtl::OUString NameUnicode;
+
+ReferenceNameRecord() : Id( 0x16 ), SizeOfName( 0 ), Reserved( 0x3E ), SizeOfNameUnicode( 0 ){}
+~ReferenceNameRecord()
+{
+}
+
+void read( SvStream* pStream )
+{
+ OSL_TRACE("NameRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> SizeOfName;
+
+ boost::scoped_array< sal_uInt8 > pName( new sal_uInt8[ SizeOfName ] );
+
+ pStream->Read( pName.get(), SizeOfName );
+ Name = svt::BinFilterUtils::CreateOUStringFromStringArray( reinterpret_cast< const char* >( pName.get() ), SizeOfName );
+
+ *pStream >> Reserved >> SizeOfNameUnicode;
+
+ boost::scoped_array< sal_uInt8 > pNameUnicode( new sal_uInt8[ SizeOfNameUnicode ] );
+ pStream->Read( pNameUnicode.get(), SizeOfNameUnicode );
+ NameUnicode = svt::BinFilterUtils::CreateOUStringFromUniStringArray( reinterpret_cast< const char* >( pNameUnicode.get() ), SizeOfName );
+}
+
+};
+
+// Baseclass for ReferenceControlRecord, ReferenceRegisteredRecord, ReferenceProjectRecord
+class DirDumper;
+
+class BaseReferenceRecord
+{
+public:
+virtual ~BaseReferenceRecord(){}
+virtual bool read( SvStream* pStream ) = 0;
+virtual void import( VBA_Impl& ){}
+};
+
+
+class ReferenceProjectRecord : public BaseReferenceRecord
+{
+public:
+ sal_uInt16 Id;
+ sal_uInt32 Size;
+ sal_uInt32 SizeOfLibidAbsolute;
+ sal_uInt32 SizeOfLibidRelative;
+ sal_uInt32 MajorVersion;
+ sal_uInt16 MinorVersion;
+ rtl::OUString AbsoluteLibid;
+ rtl::OUString RelativeLibid;
+
+ virtual bool read( SvStream* pStream );
+ virtual void import( VBA_Impl& rDir );
+ ReferenceProjectRecord();
+ ~ReferenceProjectRecord();
+};
+
+ReferenceProjectRecord::ReferenceProjectRecord() : Id( 0x000E ), Size( 0 ), SizeOfLibidAbsolute( 0 ), SizeOfLibidRelative( 0 ), MajorVersion( 0 ), MinorVersion( 0 )
+{
+}
+
+ReferenceProjectRecord::~ReferenceProjectRecord()
+{
+}
+
+bool ReferenceProjectRecord::read( SvStream* pStream )
+{
+ OSL_TRACE("ReferenceProjectRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> Size >> SizeOfLibidAbsolute;
+
+ boost::scoped_array< sal_uInt8 > pLibidAbsolute( new sal_uInt8[ SizeOfLibidAbsolute ] );
+ OSL_TRACE("ReferenceProjectRecord about to read LibidAbsolute at [0x%x]", pStream->Tell() );
+ pStream->Read( pLibidAbsolute.get(), SizeOfLibidAbsolute );
+
+ *pStream >> SizeOfLibidRelative;
+
+ boost::scoped_array< sal_uInt8 > pLibidRelative( new sal_uInt8[ SizeOfLibidRelative ] );
+ OSL_TRACE("ReferenceProjectRecord about to read LibidRelative at [0x%x]", pStream->Tell() );
+ pStream->Read( pLibidRelative.get(), SizeOfLibidRelative );
+
+ *pStream >> MajorVersion >> MinorVersion;
+
+ // array size is ORed with SVX_MSOCX_COMPRESSED to force processing of ascii bytes ( and not
+ // 16 bit unicode )
+ // the offset of 3 is needed to skip the ProjectReference "*\" and project kind ( 0x4[1-4] ) info.
+
+ AbsoluteLibid = svt::BinFilterUtils::CreateOUStringFromStringArray( reinterpret_cast< const char* >( pLibidAbsolute.get() + 3 ), (SizeOfLibidAbsolute - 3 ) );
+ RelativeLibid = svt::BinFilterUtils::CreateOUStringFromStringArray( reinterpret_cast< const char* >( pLibidRelative.get() + 3 ), ( SizeOfLibidRelative -3 ) );
+
+ OSL_TRACE("ReferenceProjectRecord - absolute path %s", rtl::OUStringToOString( AbsoluteLibid, RTL_TEXTENCODING_UTF8 ).getStr() );
+ OSL_TRACE("ReferenceProjectRecord - relative path %s", rtl::OUStringToOString( RelativeLibid, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return true;
+}
+
+void ReferenceProjectRecord::import( VBA_Impl& rDir )
+{
+ rDir.AddProjectReference( AbsoluteLibid );
+}
+
+class ReferenceRegisteredRecord : public BaseReferenceRecord
+{
+public:
+ sal_uInt16 Id;
+ sal_uInt32 Size;
+ sal_uInt32 SizeOfLibid;
+ boost::scoped_array< sal_uInt8> pLibid;
+ sal_Int32 Reserved1;
+ sal_Int16 Reserved2;
+
+ ReferenceRegisteredRecord();
+ ~ReferenceRegisteredRecord();
+ bool read( SvStream* pStream );
+};
+
+ReferenceRegisteredRecord::ReferenceRegisteredRecord() : Id( 0x000D ), Size( 0 ), SizeOfLibid( 0 ), Reserved1( 0 ), Reserved2( 0 )
+{
+}
+
+ReferenceRegisteredRecord::~ReferenceRegisteredRecord()
+{
+}
+
+bool
+ReferenceRegisteredRecord::read( SvStream* pStream )
+{
+ OSL_TRACE("ReferenceRegisteredRecord [0x%x]", pStream->Tell() );
+ *pStream >> Id >> Size >> SizeOfLibid;
+ if ( SizeOfLibid )
+ {
+ pLibid.reset( new sal_uInt8[ SizeOfLibid] );
+ pStream->Read( pLibid.get(), SizeOfLibid );
+ }
+ *pStream >> Reserved1 >> Reserved2;
+ return true;
+}
+
+class ReferenceOriginalRecord
+{
+public:
+ sal_uInt16 Id;
+ sal_uInt32 SizeOfLibOriginal;
+ boost::scoped_array< sal_uInt8 > pLibidOriginal;
+
+
+ReferenceOriginalRecord() : Id( 0x033 ), SizeOfLibOriginal( 0 )
+{
+}
+
+~ReferenceOriginalRecord()
+{
+}
+
+void read( SvStream* pStream )
+{
+ *pStream >> Id >> SizeOfLibOriginal;
+ if ( SizeOfLibOriginal )
+ {
+ pLibidOriginal.reset( new sal_uInt8[ SizeOfLibOriginal ] );
+ pStream->Read( pLibidOriginal.get(), SizeOfLibOriginal );
+ }
+}
+
+};
+
+class ReferenceControlRecord : public BaseReferenceRecord
+{
+public:
+std::auto_ptr< ReferenceOriginalRecord > OriginalRecord;
+sal_Int16 Id;
+sal_uInt32 SizeTwiddled;
+sal_uInt32 SizeOfLibidTwiddled;
+boost::shared_array< sal_uInt8 > LibidTwiddled;
+sal_uInt32 Reserved1;
+sal_uInt16 Reserved2;
+std::auto_ptr< ReferenceNameRecord > NameRecordExtended;// Optional
+sal_uInt16 Reserved3;
+sal_uInt32 SizeExtended;
+sal_uInt32 SizeOfLibidExtended;
+boost::shared_array< sal_uInt8 > LibidExtended;
+sal_uInt32 Reserved4;
+sal_uInt16 Reserved5;
+sal_uInt8 OriginalTypeLib[ 16 ];
+sal_uInt32 Cookie;
+
+ReferenceControlRecord() : Id( 0x2F ), SizeTwiddled( 0 ), SizeOfLibidTwiddled( 0 ), Reserved1( 0 ), Reserved2( 0 ), Reserved3( 0x30 ), SizeExtended( 0 ), SizeOfLibidExtended( 0 ), Reserved4( 0 ), Reserved5( 0 ), Cookie( 0 )
+{
+ for( int i = 0; i < 16; ++i )
+ OriginalTypeLib[ i ] = 0;
+}
+
+~ReferenceControlRecord()
+{
+}
+
+bool read( SvStream* pStream )
+{
+ OSL_TRACE("ReferenceControlRecord [0x%x]", pStream->Tell() );
+ long nPos = pStream->Tell();
+
+ *pStream >> Id;
+ pStream->Seek( nPos ); // point before the peeked Id
+ if ( Id == 0x33 ) // we have an OriginalRecord
+ {
+ OriginalRecord.reset( new ReferenceOriginalRecord() );
+ OriginalRecord->read( pStream );
+ }
+ *pStream >> Id >> SizeTwiddled >> SizeOfLibidTwiddled;
+
+ if ( SizeOfLibidTwiddled )
+ {
+ LibidTwiddled.reset( new sal_uInt8[ SizeOfLibidTwiddled ] );
+ pStream->Read( LibidTwiddled.get(), SizeOfLibidTwiddled );
+ }
+
+ *pStream >> Reserved1 >> Reserved2;
+
+ nPos = pStream->Tell();
+ // peek at the id for optional NameRecord
+ sal_Int16 nTmpId;
+ *pStream >> nTmpId;
+ if ( nTmpId == 0x30 )
+ {
+ Reserved3 = 0x30;
+ }
+ else
+ {
+ pStream->Seek( nPos );
+ NameRecordExtended.reset( new ReferenceNameRecord() );
+ NameRecordExtended->read( pStream );
+ *pStream >> Reserved3;
+ }
+ *pStream >> SizeExtended >> SizeOfLibidExtended;
+
+ if ( SizeExtended )
+ {
+ LibidExtended.reset( new sal_uInt8[ SizeOfLibidExtended ] );
+ pStream->Read( LibidExtended.get(), SizeOfLibidExtended );
+ }
+
+ *pStream >> Reserved4;
+ *pStream >> Reserved5;
+
+ pStream->Read( OriginalTypeLib, sizeof( OriginalTypeLib ) );
+ *pStream >> Cookie;
+ return true;
+}
+
+};
+
+class ReferenceRecord : public BaseReferenceRecord
+{
+public:
+// NameRecord is Optional
+std::auto_ptr< ReferenceNameRecord > NameRecord;
+std::auto_ptr< BaseReferenceRecord > aReferenceRecord;
+
+ReferenceRecord(){}
+~ReferenceRecord()
+{
+}
+
+// false return would mean failed to read Record e.g. end of array encountered
+// Note: this read routine will make sure the stream is pointing to where it was the
+// method was called )
+
+bool read( SvStream* pStream )
+{
+ OSL_TRACE("ReferenceRecord [0x%x]", pStream->Tell() );
+ bool bRead = true;
+ long nStart = pStream->Tell();
+ long nPos = nStart;
+ // Peek at the ID
+ sal_Int16 Id;
+ *pStream >> Id;
+ pStream->Seek( nPos ); // place back before Id
+ if ( Id == 0x16 ) // Optional NameRecord
+ {
+ NameRecord.reset( new ReferenceNameRecord() );
+ NameRecord->read( pStream );
+ }
+ else if ( Id == 0x0f )
+ {
+ pStream->Seek( nStart );
+ bRead = false;
+ return bRead; // start of module, terminate read
+ }
+
+ nPos = pStream->Tell(); // mark position, peek at next Id
+ *pStream >> Id;
+ pStream->Seek( nPos ); // place back before Id
+
+ switch( Id )
+ {
+ case 0x0D:
+ aReferenceRecord.reset( new ReferenceRegisteredRecord() );
+ break;
+ case 0x0E:
+ aReferenceRecord.reset( new ReferenceProjectRecord() );
+ break;
+ case 0x2F:
+ case 0x33:
+ aReferenceRecord.reset( new ReferenceControlRecord() );
+ break;
+ default:
+ bRead = false;
+ OSL_TRACE("Big fat error, unknown ID 0x%x", Id);
+ break;
+ }
+ if ( bRead )
+ aReferenceRecord->read( pStream );
+ return bRead;
+}
+
+void import( VBA_Impl& rVBA )
+{
+ if ( aReferenceRecord.get() )
+ aReferenceRecord->import( rVBA );
+}
+
+};
+
+class DirDumper
+{
+public:
+ProjectSysKindRecord mSysKindRec;
+ProjectLcidRecord mLcidRec;
+ProjectLcidInvokeRecord mLcidInvokeRec;
+ProjectCodePageRecord mCodePageRec;
+ProjectNameRecord mProjectNameRec;
+ProjectDocStringRecord mDocStringRec;
+ProjectHelpFilePath mHelpFileRec;
+ProjectHelpContextRecord mHelpContextRec;
+ProjectLibFlagsRecord mLibFlagsRec;
+ProjectVersionRecord mVersionRec;
+ProjectConstantsRecord mConstantsRecord;
+std::vector< ReferenceRecord* > ReferenceArray;
+
+DirDumper() {}
+~DirDumper()
+{
+ for ( std::vector< ReferenceRecord* >::iterator it = ReferenceArray.begin(); it != ReferenceArray.end(); ++it )
+ delete *it;
+
+}
+
+void read( SvStream* pStream )
+{
+ sal_Int32 nPos = pStream->Tell();
+#ifdef DEBUG
+ std::ofstream aDump("dir.dump");
+ while ( !pStream->IsEof() )
+ {
+ sal_Int8 aByte;
+ *pStream >> aByte;
+ aDump << aByte;
+ }
+ aDump.flush();
+#endif
+ pStream->Seek( nPos );
+ readProjectInformation( pStream );
+ readProjectReferenceInformation( pStream );
+}
+
+void readProjectReferenceInformation( SvStream* pStream )
+{
+ bool bKeepReading = true;
+ while( bKeepReading )
+ {
+ ReferenceRecord* pRef = new ReferenceRecord();
+ bKeepReading = pRef->read( pStream );
+ if ( bKeepReading )
+ ReferenceArray.push_back( pRef );
+ }
+}
+
+void readProjectInformation( SvStream* pStream )
+{
+ mSysKindRec.read( pStream );
+ mLcidRec.read( pStream );
+ mLcidInvokeRec.read( pStream );
+ mCodePageRec.read( pStream );
+ mProjectNameRec.read( pStream );
+ mDocStringRec.read( pStream );
+ mHelpFileRec.read( pStream );
+ mHelpContextRec.read( pStream );
+ mLibFlagsRec.read( pStream );
+ mVersionRec.read( pStream );
+ sal_Int32 nPos = pStream->Tell();
+ sal_uInt16 nTmp;
+ *pStream >> nTmp;
+ if ( nTmp == 0x0C )
+ {
+ pStream->Seek( nPos );
+ mConstantsRecord.read( pStream );
+ }
+ OSL_TRACE("After Information pos is 0x%x", pStream->Tell() );
+}
+
+void import( VBA_Impl& rVBA )
+{
+ // get project references
+ for ( std::vector< ReferenceRecord* >::iterator it = ReferenceArray.begin(); it != ReferenceArray.end(); ++it )
+ (*it)->import( rVBA );
+ rVBA.SetProjectName( mProjectNameRec.ProjectName );
+
+}
+};
+
+
/*
A few urls which may in the future be of some use
http://www.virusbtn.com/vb2000/Programme/papers/bontchev.pdf
@@ -155,7 +948,21 @@ int VBA_Impl::ReadVBAProject(const SvStorageRef &rxVBAStorage)
xVBAProject = rxVBAStorage->OpenSotStream(
String( RTL_CONSTASCII_USTRINGPARAM( "_VBA_PROJECT" ) ),
STREAM_STD_READ | STREAM_NOCREATE );
-
+ // read Dir stream
+ SvStorageStreamRef xDir = rxVBAStorage->OpenSotStream(
+ String( RTL_CONSTASCII_USTRINGPARAM( "dir" ) ),
+ STREAM_STD_READ | STREAM_NOCREATE );
+// disable read and import of Dir stream bits, e.g. project references and
+// project name for 3.1 ( a bit unstable yet )
+#if 1
+ // decompress the stream
+ std::auto_ptr< SvMemoryStream > xCmpDir;
+ xCmpDir.reset( MSLZSS::decompressAsStream( xDir, 0 ) );
+ // try to parse the dir stream
+ DirDumper dDump;
+ dDump.read( xCmpDir.get() );
+ dDump.import( *this );
+#endif
if( !xVBAProject.Is() || SVSTREAM_OK != xVBAProject->GetError() )
{
DBG_WARNING("Not able to find vba project, cannot find macros");
@@ -416,6 +1223,7 @@ bool VBA_Impl::Open( const String &rToplevel, const String &rSublevel )
if( !xMacros.Is() || SVSTREAM_OK != xMacros->GetError() )
{
DBG_WARNING("No Macros Storage");
+ OSL_TRACE("No Macros Storage");
}
else
{
@@ -425,6 +1233,7 @@ bool VBA_Impl::Open( const String &rToplevel, const String &rSublevel )
if( !xVBA.Is() || SVSTREAM_OK != xVBA->GetError() )
{
DBG_WARNING("No Visual Basic in Storage");
+ OSL_TRACE("No Visual Basic in Storage");
}
else
{
@@ -439,6 +1248,7 @@ bool VBA_Impl::Open( const String &rToplevel, const String &rSublevel )
* ( value ) is either a Class Module, Form Module or a plain VB Module. */
SvStorageStreamRef xProject = xMacros->OpenSotStream(
String( RTL_CONSTASCII_USTRINGPARAM( "PROJECT" ) ) );
+
SvStorageStream* pStp = xProject;
UniString tmp;
static const String sThisDoc( RTL_CONSTASCII_USTRINGPARAM( "ThisDocument" ) );
diff --git a/filter/source/msfilter/msvbasic.hxx b/filter/source/msfilter/msvbasic.hxx
index 171671e8cd5c..39d35ee68ae6 100644
--- a/filter/source/msfilter/msvbasic.hxx
+++ b/filter/source/msfilter/msvbasic.hxx
@@ -36,6 +36,8 @@
#include <tools/dynary.hxx>
#include <vector>
#include <map>
+#include <com/sun/star/script/ModuleType.hpp>
+using namespace ::com::sun::star::script::ModuleType;
/* class VBA:
* The VBA class provides a set of methods to handle Visual Basic For
@@ -86,8 +88,14 @@ public:
//
// #117718# member map of module names to types of module
ModType GetModuleType( const UniString& rModuleName );
- std::vector<String> maReferences;
+ rtl::OUString& ProjectName() { return msProjectName; }
+ void SetProjectName( const rtl::OUString& rPName ) { msProjectName = rPName; }
+ const std::vector<rtl::OUString>& ProjectReferences() { return maPrjReferences; }
+ void AddProjectReference( const rtl::OUString& rProject ) { maPrjReferences.push_back( rProject); }
+ SvStorage* GetStorage() { return xStor; }
private:
+ std::vector<rtl::OUString> maReferences;
+ std::vector<rtl::OUString> maPrjReferences;
struct VBAOffset_Impl
{
String sName;
@@ -113,6 +121,7 @@ private:
int ReadVBAProject(const SvStorageRef &rxVBAStorage);
int DecompressVBA(int index, SvStorageStreamRef &rxVBAStream);
sal_uInt8 ReadPString(SvStorageStreamRef &xVBAProject, bool bIsUnicode);
+ rtl::OUString msProjectName;
};
#endif
diff --git a/filter/source/msfilter/svxmsbas.cxx b/filter/source/msfilter/svxmsbas.cxx
index 73af7161fcac..ea5c58fb44be 100644
--- a/filter/source/msfilter/svxmsbas.cxx
+++ b/filter/source/msfilter/svxmsbas.cxx
@@ -66,6 +66,27 @@ using rtl::OUString;
static ::rtl::OUString sVBAOption( RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) );
+void SvxImportMSVBasic::extractAttribute( const String& rAttribute, const String& rModName )
+{
+ // format of the attribute we are interested in is
+ // Attribute VB_Control = "ControlName", intString, MSForms, ControlTypeAsString
+ // e.g.
+ // Attribute VB_Control = "CommandButton1, 201, 19, MSForms, CommandButton"
+ String sControlAttribute( RTL_CONSTASCII_USTRINGPARAM("Attribute VB_Control = \"") );
+ if ( rAttribute.Search( sControlAttribute ) != STRING_NOTFOUND )
+ {
+ String sRest = rAttribute.Copy( sControlAttribute.Len() );
+ xub_StrLen nPos = 0;
+ String sCntrlName = sRest.GetToken( 0, ',', nPos );
+
+ sal_Int32 nCntrlId = sRest.GetToken( 0, ',', nPos).ToInt32();
+ OSL_TRACE("In module %s, assiging %d controlname %s",
+ rtl::OUStringToOString( rModName, RTL_TEXTENCODING_UTF8 ).getStr(), nCntrlId,
+ rtl::OUStringToOString( sCntrlName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ m_ModuleNameToObjIdHash[ rModName ][ nCntrlId ] = sCntrlName;
+ }
+}
+
int SvxImportMSVBasic::Import( const String& rStorageName,
const String &rSubStorageName,
BOOL bAsComment, BOOL bStripped )
@@ -73,19 +94,19 @@ int SvxImportMSVBasic::Import( const String& rStorageName,
std::vector< String > codeNames;
return Import( rStorageName, rSubStorageName, codeNames, bAsComment, bStripped );
}
-
int SvxImportMSVBasic::Import( const String& rStorageName,
const String &rSubStorageName,
const std::vector< String >& codeNames,
BOOL bAsComment, BOOL bStripped )
{
+ msProjectName = rtl::OUString();
int nRet = 0;
if( bImport && ImportCode_Impl( rStorageName, rSubStorageName, codeNames,
bAsComment, bStripped ))
nRet |= 1;
if (bImport)
- ImportForms_Impl(rStorageName, rSubStorageName);
+ ImportForms_Impl(rStorageName, rSubStorageName, !bAsComment);
if( bCopy && CopyStorage_Impl( rStorageName, rSubStorageName ))
nRet |= 2;
@@ -94,9 +115,44 @@ int SvxImportMSVBasic::Import( const String& rStorageName,
}
bool SvxImportMSVBasic::ImportForms_Impl(const String& rStorageName,
- const String& rSubStorageName)
+ const String& rSubStorageName, BOOL bVBAMode )
+{
+ BOOL bRet = FALSE;
+ // #FIXME VBA_Impl ( or some other new class ) should handle both userforms
+ // and code
+ VBA_Impl aVBA( *xRoot, TRUE );
+ // This call is a waste we read the source ( again ) only to get the refereneces
+ // *AGAIN*, we really need to rewrite all of this
+ aVBA.Open( rStorageName, rSubStorageName );
+
+ bRet = ImportForms_Impl( aVBA, rStorageName, rSubStorageName, bVBAMode );
+ std::vector<rtl::OUString> sProjectRefs = aVBA.ProjectReferences();
+
+ for ( std::vector<rtl::OUString>::iterator it = sProjectRefs.begin(); it != sProjectRefs.end(); ++it )
+ {
+ rtl::OUString sFileName = *it;
+#ifndef WIN
+#ifdef DEBUG
+ // hacky test code to read referenced projects on linux
+ sal_Int32 nPos = (*it).lastIndexOf('\\');
+ sFileName = (*it).copy( nPos + 1 );
+ sFileName = rtl::OUString::createFromAscii("~/Documents/") + sFileName;
+#endif
+#endif
+ SotStorageRef rRoot = new SotStorage( sFileName, STREAM_STD_READWRITE, STORAGE_TRANSACTED );
+ VBA_Impl refVBA( *rRoot, TRUE );
+ refVBA.Open( rStorageName, rSubStorageName );
+ // The return from ImportForms doesn't indicate and error ( it could )
+ // but also it just means no userforms were imported
+ if ( ImportForms_Impl( refVBA, rStorageName, rSubStorageName, bVBAMode ) )
+ bRet = true; // mark that at least on userform was imported
+ }
+ return bRet;
+}
+
+bool SvxImportMSVBasic::ImportForms_Impl( VBA_Impl& rVBA, const String& rStorageName, const String& rSubStorageName, BOOL bVBAMode )
{
- SvStorageRef xVBAStg(xRoot->OpenSotStorage(rStorageName,
+ SvStorageRef xVBAStg(rVBA.GetStorage()->OpenSotStorage(rStorageName,
STREAM_READWRITE | STREAM_NOCREATE | STREAM_SHARE_DENYALL));
if (!xVBAStg.Is() || xVBAStg->GetError())
return false;
@@ -129,6 +185,10 @@ bool SvxImportMSVBasic::ImportForms_Impl(const String& rStorageName,
DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+
+ if (rVBA.ProjectName().getLength() )
+ aLibName = rVBA.ProjectName();
+ OSL_TRACE( "userformage lib name %s", rtl::OUStringToOString( aLibName, RTL_TEXTENCODING_UTF8 ).getStr() );
Reference<XNameContainer> xLib;
if (xLibContainer.is())
{
@@ -178,7 +238,17 @@ bool SvxImportMSVBasic::ImportForms_Impl(const String& rStorageName,
xSF->createInstance(
OUString(RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.awt.UnoControlDialogModel"))), uno::UNO_QUERY);
-
+ // #FIXME HACK - mark the Model with the VBA mode
+ // In vba mode the imported userform uses 100th mm as units
+ // or geometry
+ // In non vba mode MAP_APPFONT is used ( same as normal basic
+ // dialogs
+ if ( bVBAMode )
+ {
+ Reference<XPropertySet> xDlgProps(xDialog, UNO_QUERY);
+ if ( xDlgProps.is() )
+ xDlgProps->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("VBAForm") ), uno::makeAny( sal_True ) );
+ }
OCX_UserForm aForm(xVBAStg, *aIter, *aIter, xDialog, xSF );
aForm.pDocSh = &rDocSh;
sal_Bool bOk = aForm.Read(xTypes);
@@ -247,8 +317,34 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
{
BOOL bRet = FALSE;
VBA_Impl aVBA( *xRoot, bAsComment );
+
if( aVBA.Open(rStorageName,rSubStorageName) )
{
+ msProjectName = aVBA.ProjectName();
+
+ if ( msProjectName.getLength() )
+ rDocSh.GetBasicManager()->SetName( msProjectName ); // set name of Project
+
+ bRet = ImportCode_Impl( aVBA, codeNames, bAsComment, bStripped );
+ std::vector<rtl::OUString> sProjectRefs = aVBA.ProjectReferences();
+
+ for ( std::vector<rtl::OUString>::iterator it = sProjectRefs.begin(); it != sProjectRefs.end(); ++it )
+ {
+ rtl::OUString sFileName = *it;
+ OSL_TRACE("referenced project %s ", rtl::OUStringToOString( sFileName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ SotStorageRef rRoot = new SotStorage( sFileName, STREAM_STD_READWRITE, STORAGE_TRANSACTED );
+ VBA_Impl refVBA( *rRoot, bAsComment );
+ std::vector< String > codeNamesNone;
+ if( refVBA.Open(rStorageName,rSubStorageName) && ImportCode_Impl( refVBA, codeNamesNone, bAsComment, bStripped ) )
+ bRet = TRUE; // mark that some code was imported
+ }
+ }
+ return bRet;
+}
+
+BOOL SvxImportMSVBasic::ImportCode_Impl( VBA_Impl& aVBA, const std::vector< String >& codeNames, BOOL bAsComment, BOOL bStripped )
+{
+ BOOL bRet = FALSE;
SFX_APP()->EnterBasicCall();
Reference<XLibraryContainer> xLibContainer = rDocSh.GetBasicContainer();
DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
@@ -269,6 +365,8 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
UINT16 nStreamCount = aVBA.GetNoStreams();
Reference<XNameContainer> xLib;
String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
+ if ( aVBA.ProjectName().getLength() )
+ aLibName = aVBA.ProjectName();
if( xLibContainer.is() && nStreamCount )
{
if( !xLibContainer->hasByName( aLibName ) )
@@ -417,7 +515,11 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
if( nEnd == STRING_NOTFOUND )
pStr->Erase();
else
+ {
+ String sAttr= pStr->Copy( nBegin, (nEnd-nBegin)+1);
+ extractAttribute( sAttr, sModule );
pStr->Erase(nBegin, (nEnd-nBegin)+1);
+ }
}
}
if( aDecompressed.Get(j)->Len() )
@@ -496,7 +598,6 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
bRet = true;
}
SFX_APP()->LeaveBasicCall();
- }
return bRet;
}
diff --git a/oox/inc/oox/ole/vbacontrol.hxx b/oox/inc/oox/ole/vbacontrol.hxx
index c2490b3506bf..bc443108f5bd 100644..100755
--- a/oox/inc/oox/ole/vbacontrol.hxx
+++ b/oox/inc/oox/ole/vbacontrol.hxx
@@ -29,6 +29,7 @@
#define OOX_OLE_VBACONTROL_HXX
#include "oox/ole/axcontrol.hxx"
+#include <com/sun/star/frame/XModel.hpp>
namespace com { namespace sun { namespace star {
namespace container { class XNameContainer; }
@@ -192,6 +193,7 @@ public:
/** Imports the form and its embedded controls, and inserts the form with
all its controls into the passed dialog library. */
void importForm(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxDialogLib,
StorageBase& rVbaFormStrg,
const ::rtl::OUString& rModuleName,
diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx
index 218163b70286..386c1a034641 100644..100755
--- a/oox/source/ole/vbacontrol.cxx
+++ b/oox/source/ole/vbacontrol.cxx
@@ -58,6 +58,7 @@ using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::UNO_SET_THROW;
using ::com::sun::star::uno::XComponentContext;
+using ::com::sun::star::frame::XModel;
namespace oox {
namespace ole {
@@ -759,7 +760,7 @@ VbaUserForm::VbaUserForm( const Reference< XMultiServiceFactory >& rxGlobalFacto
OSL_ENSURE( mxGlobalFactory.is(), "VbaUserForm::VbaUserForm - missing service factory" );
}
-void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib,
+void VbaUserForm::importForm( const Reference< XModel >& rxDocModel, const Reference< XNameContainer >& rxDialogLib,
StorageBase& rVbaFormStrg, const OUString& rModuleName, rtl_TextEncoding eTextEnc )
{
OSL_ENSURE( rxDialogLib.is(), "VbaUserForm::importForm - missing dialog library" );
@@ -830,7 +831,7 @@ void VbaUserForm::importForm( const Reference< XNameContainer >& rxDialogLib,
// export the dialog to XML and insert it into the dialog library
PropertySet aFactoryProps( mxGlobalFactory );
Reference< XComponentContext > xCompContext( aFactoryProps.getAnyProperty( PROP_DefaultContext ), UNO_QUERY_THROW );
- Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, xCompContext ), UNO_SET_THROW );
+ Reference< XInputStreamProvider > xDialogSource( ::xmlscript::exportDialogModel( xDialogNC, xCompContext, rxDocModel ), UNO_SET_THROW );
OSL_ENSURE( !rxDialogLib->hasByName( aFormName ), "VbaUserForm::importForm - multiple dialogs with equal name" );
ContainerHelper::insertByName( rxDialogLib, aFormName, Any( xDialogSource ) );
}
diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx
index c7830582d0ef..fad2dba04ffa 100644..100755
--- a/oox/source/ole/vbaproject.cxx
+++ b/oox/source/ole/vbaproject.cxx
@@ -419,7 +419,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
// create and import the form
Reference< XNameContainer > xDialogLib( createDialogLibrary(), UNO_SET_THROW );
VbaUserForm aForm( mxGlobalFactory, rGraphicHelper, bDefaultColorBgr );
- aForm.importForm( xDialogLib, *xSubStrg, aModuleName, eTextEnc );
+ aForm.importForm( mxDocModel, xDialogLib, *xSubStrg, aModuleName, eTextEnc );
}
catch( Exception& )
{