summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Power <noel.power@novell.com>2010-11-02 15:59:53 +0000
committerNoel Power <noel.power@novell.com>2010-11-02 19:49:48 +0000
commite274ec121b99173740dd39755232184b0a2dcc23 (patch)
tree7be90cea076ab0da5f3dda14bd03edb53e4b1643
parentfe6bb7efcfa97b7a5ac02fa951e67f6c609a859d (diff)
initial import of latest cws container_controls
-rw-r--r--filter/inc/filter/msfilter/msocximex.hxx377
-rw-r--r--filter/source/msfilter/msocximex.cxx2255
-rw-r--r--filter/source/msfilter/msvbahelper.cxx15
-rw-r--r--oox/inc/oox/helper/containerhelper.hxx14
-rw-r--r--oox/inc/oox/ole/axcontrol.hxx16
-rw-r--r--oox/inc/oox/ole/vbacontrol.hxx24
-rw-r--r--oox/inc/oox/ole/vbahelper.hxx1
-rw-r--r--oox/inc/oox/ole/vbamodule.hxx25
-rw-r--r--oox/inc/oox/ole/vbaproject.hxx32
-rw-r--r--oox/inc/oox/xls/drawingfragment.hxx5
-rw-r--r--oox/inc/oox/xls/excelfilter.hxx15
-rw-r--r--oox/prj/d.lst1
-rw-r--r--oox/source/core/facreg.cxx6
-rw-r--r--oox/source/ole/axcontrol.cxx201
-rw-r--r--oox/source/ole/makefile.mk3
-rwxr-xr-xoox/source/ole/vbacontrol.cxx360
-rw-r--r--oox/source/ole/vbamodule.cxx189
-rwxr-xr-xoox/source/ole/vbaproject.cxx67
-rw-r--r--oox/source/token/properties.txt3
-rw-r--r--oox/source/token/tokenmap.cxx2
-rw-r--r--oox/source/vml/vmldrawing.cxx2
-rw-r--r--oox/source/xls/drawingfragment.cxx111
-rw-r--r--oox/source/xls/excelfilter.cxx92
-rw-r--r--oox/source/xls/workbookhelper.cxx1
24 files changed, 2060 insertions, 1757 deletions
diff --git a/filter/inc/filter/msfilter/msocximex.hxx b/filter/inc/filter/msfilter/msocximex.hxx
index 7269b1f7f5bb..829c029a469b 100644
--- a/filter/inc/filter/msfilter/msocximex.hxx
+++ b/filter/inc/filter/msfilter/msocximex.hxx
@@ -294,6 +294,8 @@ public:
rtl::OUString msCtrlSource;
rtl::OUString msRowSource;
SfxObjectShell *pDocSh;
+ ::rtl::OUString sImageUrl;
+ com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicObject> mxGrfObj;
protected:
sal_uInt32 ImportColor(sal_uInt32 nColorCode) const;
@@ -416,22 +418,23 @@ public:
sal_uInt8 pPictureHeader[20];
sal_uInt32 nPictureLen;
- ::rtl::OUString sImageUrl;
- com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicObject> mxGrfObj;
};
class OCX_TabStrip : public OCX_Control
{
public:
- OCX_TabStrip() : OCX_Control( rtl::OUString::createFromAscii("TabStrip")) {}
+ OCX_TabStrip() : OCX_Control( rtl::OUString::createFromAscii("TabStrip")), nIdentifier(0), nFixedAreaLen(0), nNumTabs(0), bHasTabs(true) {}
+
virtual sal_Bool ReadFontData(SotStorageStream *pS);
virtual sal_Bool Read(SotStorageStream *pS);
+ std::vector< rtl::OUString > msItems;
sal_uInt16 nIdentifier;
sal_uInt16 nFixedAreaLen;
sal_uInt8 pBlockFlags[4];
- sal_uInt16 nNumTabs;
+ sal_Int32 nNumTabs;
+ bool bHasTabs;
};
class OCX_Image : public OCX_Control
@@ -465,8 +468,6 @@ public:
sal_uInt8 nSpecialEffect;
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
@@ -487,8 +488,7 @@ public:
};
struct ContainerRecord
{
- ContainerRecord():nTop(0), nLeft(0), nSubStorageId(0), nSubStreamLen(0), nTabPos(0), nTypeIdent(0), bVisible( true ) {}
-
+ ContainerRecord():nTop(0), nLeft(0), nSubStorageId(0), nSubStreamLen(0), nTabPos(0), nTypeIdent(0), bVisible( true ), bTabStop( true ) {}
::rtl::OUString cName;
::rtl::OUString controlTip;
::rtl::OUString sCtrlSource;
@@ -501,6 +501,7 @@ struct ContainerRecord
sal_uInt16 nTabPos;
sal_uInt16 nTypeIdent;
bool bVisible;
+ bool bTabStop;
};
typedef std::vector<OCX_Control*>::iterator CtrlIterator;
@@ -509,44 +510,32 @@ typedef std::vector<OCX_Control*> CtrlList;
class OCX_OptionButton;
-class OCX_ContainerControl : public OCX_Control
+class OCX_ParentControl : public OCX_Control
{
public:
- virtual ~OCX_ContainerControl();
- // sub class will process the control specific information
- // e.g frame or userform ( maybe tab, mulipage in the future )
- // Base (this) class will process the container specific information
- // e.g. the controls contained by this container
- // will
- // a) create the controls
- // b) read the controls
- // c) store these controls in a list for post processing
- // e.g. import
- //
virtual sal_Bool Read(SvStorageStream *pS);
- // No Font record
virtual sal_Bool ReadFontData(SvStorageStream* /*pS*/) { return sal_True; }
using OCX_Control::Import; // to not hide the other two import methods
+
virtual sal_Bool Import(com::sun::star::uno::Reference<
com::sun::star::beans::XPropertySet> &rPropSet);
SotStorageStreamRef getContainerStream() { return mContainerStream; }
+ SotStorageStreamRef getOStream() { return mContainedControlsStream; }
virtual void ProcessControl( OCX_Control* pControl, SvStorageStream* pS, ContainerRecord& rec );
- bool createFromContainerRecord( ContainerRecord& record,
+ bool createFromContainerRecord( const ContainerRecord& record,
OCX_Control*& );
SotStorageStreamRef getContainedControlsStream(){ return mContainedControlsStream; }
protected:
- // This class not meant to be instantiated
- // needs to be subclassed
- OCX_ContainerControl( SotStorageRef& parent,
+ OCX_ParentControl( SotStorageRef& parent,
const ::rtl::OUString& storageName,
const ::rtl::OUString& sN,
const com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer > &rParent,
+ com::sun::star::container::XNameContainer > &rDialog,
OCX_Control* pParent = NULL );
- rtl::OUString createSubStreamName( const sal_uInt32& subStorageID );
+ ~OCX_ParentControl();
com::sun::star::uno::Reference<
com::sun::star::container::XNameContainer > mxParent;
@@ -555,84 +544,56 @@ protected:
SotStorageRef mContainerStorage;
SotStorageStreamRef mContainerStream;
SotStorageStreamRef mContainedControlsStream;
- sal_uInt32 nNoRecords;
- sal_uInt32 nTotalLen;
- sal_uInt32 containerType;
-
-private:
- OCX_ContainerControl(); // not implemented
- OCX_ContainerControl(const OCX_ContainerControl&); // not implemented
-};
-
-
-class OCX_MultiPage : public OCX_ContainerControl
-{
-public:
- OCX_MultiPage( SotStorageRef& parent,
- const ::rtl::OUString& storageName,
- const ::rtl::OUString& sN,
- const com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer > &rDialog, OCX_Control* pParent = NULL);
- virtual ~OCX_MultiPage()
- {
- delete[] pCaption;
- delete[] pIcon;
- delete[] pPicture;
- }
- virtual sal_Bool Read(SvStorageStream *pS);
-
- using OCX_ContainerControl::Import; // to not hide the other two import methods
- virtual sal_Bool Import(com::sun::star::uno::Reference<
- com::sun::star::beans::XPropertySet> &rPropSet);
- virtual sal_Bool Import(com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer>
- &rDialog);
- virtual void ProcessControl( OCX_Control* pControl, SvStorageStream* pS, ContainerRecord& rec );
- /*sal_uInt8 for sal_uInt8 Word Struct*/
sal_uInt16 nIdentifier;
sal_uInt16 nFixedAreaLen;
sal_uInt8 pBlockFlags[4];
- sal_uInt32 fUnknown1;
+ sal_uInt32 nChildrenA;
+ sal_uInt32 nNextAvailableID;
+ sal_uInt32 nBooleanProperties;
+ sal_uInt32 nGroupCnt;
+ sal_uInt32 nZoom;
- sal_uInt8 fUnknown2:1;
+ sal_uInt8 fUnknown1:1;
sal_uInt8 fEnabled:1;
sal_uInt8 fLocked:1;
sal_uInt8 fBackStyle:1;
- sal_uInt8 fUnknown3:4;
+ sal_uInt8 fUnknown2:4;
- sal_uInt8 fUnknown4:8;
+ sal_uInt8 fUnknown3:8;
- sal_uInt8 fUnknown5:7;
+ sal_uInt8 fUnknown4:7;
sal_uInt8 fWordWrap:1;
- sal_uInt8 fUnknown6:4;
+ sal_uInt8 fUnknown5:4;
sal_uInt8 fAutoSize:1;
- sal_uInt8 fUnknown7:3;
+ sal_uInt8 fUnknown6:3;
sal_uInt32 nCaptionLen;
sal_uInt16 nVertPos;
sal_uInt16 nHorzPos;
- sal_uInt8 nMousePointer;
sal_uInt32 nBorderColor;
- sal_uInt32 fUnknown8;
- sal_uInt32 fUnknown9;
+ sal_uInt32 nDrawBuffer;
+ sal_uInt32 nShapeCookie;
sal_uInt8 nKeepScrollBarsVisible;
sal_uInt8 nCycle;
- sal_uInt16 nBorderStyle;
- sal_uInt16 nSpecialEffect;
+ sal_uInt8 nBorderStyle;
+ sal_uInt8 nMousePointer;
+ sal_uInt8 nSpecialEffect;
sal_uInt16 nPicture;
sal_uInt8 nPictureAlignment;
sal_uInt8 nPictureSizeMode;
bool bPictureTiling;
sal_uInt16 nAccelerator;
sal_uInt16 nIcon;
+ sal_uInt16 fUnknown7;
char *pCaption;
sal_uInt32 nScrollWidth;
sal_uInt32 nScrollHeight;
-
+ sal_uInt32 nScrollLeft;
+ sal_uInt32 nScrollTop;
sal_uInt8 pIconHeader[20];
sal_uInt32 nIconLen;
@@ -640,253 +601,91 @@ public:
sal_uInt8 pPictureHeader[20];
sal_uInt32 nPictureLen;
- sal_uInt8 *pPicture;
private:
- sal_Int32 mnCurrentPageStep;
-};
-
+ OCX_ParentControl(); // not implemented
+ OCX_ParentControl(const OCX_ParentControl&); // not implemented
+};
-class OCX_Page : public OCX_ContainerControl
+class OCX_Page;
+class OCX_MultiPage : public OCX_ParentControl
{
public:
- OCX_Page( SotStorageRef& parentStorage,
+ OCX_MultiPage( SotStorageRef& parent,
const ::rtl::OUString& storageName,
const ::rtl::OUString& sN,
const com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer > &rDialog, OCX_Control* parent = NULL);
- virtual ~OCX_Page()
- {
- delete[] pCaption;
- delete[] pIcon;
- delete[] pPicture;
- }
+ com::sun::star::container::XNameContainer > &rDialog, OCX_Control* pParent = NULL);
+
virtual sal_Bool Read(SvStorageStream *pS);
- using OCX_ContainerControl::Import; // to not hide the other two import methods
+ using OCX_ParentControl::Import; // to not hide the other two import methods
virtual sal_Bool Import(com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer>
- &rDialog);
-/* virtual sal_Bool Import(com::sun::star::uno::Reference<
com::sun::star::beans::XPropertySet> &rPropSet);
-*/
- /*sal_uInt8 for sal_uInt8 Word Struct*/
- sal_uInt16 nIdentifier;
- sal_uInt16 nFixedAreaLen;
- sal_uInt8 pBlockFlags[4];
-
- sal_uInt32 fUnknown1;
-
- sal_uInt8 fUnknown2:1;
- sal_uInt8 fEnabled:1;
- sal_uInt8 fLocked:1;
- sal_uInt8 fBackStyle:1;
- sal_uInt8 fUnknown3:4;
-
- sal_uInt8 fUnknown4:8;
-
- sal_uInt8 fUnknown5:7;
- sal_uInt8 fWordWrap:1;
-
- sal_uInt8 fUnknown6:4;
- sal_uInt8 fAutoSize:1;
- sal_uInt8 fUnknown7:3;
-
- sal_uInt32 nCaptionLen;
- sal_uInt16 nVertPos;
- sal_uInt16 nHorzPos;
- sal_uInt8 nMousePointer;
- sal_uInt32 nBorderColor;
- sal_uInt32 fUnknown8;
- sal_uInt32 fUnknown9;
- sal_uInt8 nKeepScrollBarsVisible;
- sal_uInt8 nCycle;
- sal_uInt16 nBorderStyle;
- sal_uInt16 nSpecialEffect;
- sal_uInt16 nPicture;
- sal_uInt8 nPictureAlignment;
- sal_uInt8 nPictureSizeMode;
- bool bPictureTiling;
- sal_uInt16 nAccelerator;
- sal_uInt16 nIcon;
-
- char *pCaption;
-
- sal_uInt32 nScrollWidth;
- sal_uInt32 nScrollHeight;
+ virtual void ProcessControl( OCX_Control* pControl, SvStorageStream* pS, ContainerRecord& rec );
+private:
+ sal_Int32 nActiveTab;
+ SotStorageStreamRef mXStream;
+ bool bHasTabs;
+ std::vector< rtl::OUString > sCaptions;
+ // order of Ids corrosponds to the order of captions above
+ std::vector< sal_Int32 > mPageIds;
+ std::hash_map< sal_Int32, OCX_Page* > idToPage;
+};
- sal_uInt8 pIconHeader[20];
- sal_uInt32 nIconLen;
- sal_uInt8 *pIcon;
+class OCX_Page : public OCX_ParentControl
+{
+public:
+ OCX_Page( SotStorageRef& parentStorage,
+ sal_Int32 nID,
+ const ::rtl::OUString& sN,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > &rDialog, OCX_Control* parent = NULL);
+ virtual sal_Bool Read(SvStorageStream *pS);
- sal_uInt8 pPictureHeader[20];
- sal_uInt32 nPictureLen;
- sal_uInt8 *pPicture;
+ using OCX_ParentControl::Import; // to not hide the other two import methods
+ virtual sal_Bool Import(com::sun::star::uno::Reference<
+ com::sun::star::beans::XPropertySet> &rPropSet);
+ rtl::OUString msTitle; // #FIXME we should use the existing caption
+ sal_Int32 mnID;
private:
};
-class OCX_Frame : public OCX_ContainerControl
+class OCX_Frame : public OCX_ParentControl
{
public:
OCX_Frame( SotStorageRef& parent,
- const ::rtl::OUString& storageName,
- const ::rtl::OUString& sN,
- const com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer > &rDialog, OCX_Control* pParent = NULL);
- virtual ~OCX_Frame()
- {
- delete[] pCaption;
- delete[] pIcon;
- delete[] pPicture;
- }
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > &rDialog, OCX_Control* pParent = NULL);
virtual sal_Bool Read(SvStorageStream *pS);
- using OCX_ContainerControl::Import; // to not hide the other two import methods
+ using OCX_ParentControl::Import; // to not hide the other two import methods
virtual sal_Bool Import(com::sun::star::uno::Reference<
com::sun::star::beans::XPropertySet> &rPropSet);
-
- /*sal_uInt8 for sal_uInt8 Word Struct*/
- sal_uInt16 nIdentifier;
- sal_uInt16 nFixedAreaLen;
- sal_uInt8 pBlockFlags[4];
-
- sal_uInt32 fUnknown1;
-
- sal_uInt8 fUnknown2:1;
- sal_uInt8 fEnabled:1;
- sal_uInt8 fLocked:1;
- sal_uInt8 fBackStyle:1;
- sal_uInt8 fUnknown3:4;
-
- sal_uInt8 fUnknown4:8;
-
- sal_uInt8 fUnknown5:7;
- sal_uInt8 fWordWrap:1;
-
- sal_uInt8 fUnknown6:4;
- sal_uInt8 fAutoSize:1;
- sal_uInt8 fUnknown7:3;
-
- sal_uInt32 nCaptionLen;
- sal_uInt16 nVertPos;
- sal_uInt16 nHorzPos;
- sal_uInt8 nMousePointer;
- sal_uInt32 nBorderColor;
- sal_uInt32 fUnknown8;
- sal_uInt32 fUnknown9;
- sal_uInt8 nKeepScrollBarsVisible;
- sal_uInt8 nCycle;
- sal_uInt16 nBorderStyle;
- sal_uInt16 nSpecialEffect;
- sal_uInt16 nPicture;
- sal_uInt8 nPictureAlignment;
- sal_uInt8 nPictureSizeMode;
- bool bPictureTiling;
- sal_uInt16 nAccelerator;
- sal_uInt16 nIcon;
-
- char *pCaption;
-
- sal_uInt32 nScrollWidth;
- sal_uInt32 nScrollHeight;
- sal_uInt32 nScrollLeft;
- sal_uInt32 nScrollTop;
-
-
- sal_uInt8 pIconHeader[20];
- sal_uInt32 nIconLen;
- sal_uInt8 *pIcon;
-
- sal_uInt8 pPictureHeader[20];
- sal_uInt32 nPictureLen;
- sal_uInt8 *pPicture;
-private:
};
-class OCX_UserForm : public OCX_ContainerControl
+
+class OCX_UserForm : public OCX_ParentControl
{
public:
OCX_UserForm( SotStorageRef& parent,
- const ::rtl::OUString& storageName,
- const ::rtl::OUString& sN,
- const com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer > &rDialog,
- const com::sun::star::uno::Reference<
- com::sun::star::lang::XMultiServiceFactory >& rMsf);
- ~OCX_UserForm()
- {
- delete[] pCaption;
- delete[] pIcon;
- }
-
- virtual sal_Bool Read(SvStorageStream *pS);
-
- using OCX_ContainerControl::Import; // to not hide the other two import methods
+ const ::rtl::OUString& storageName,
+ const ::rtl::OUString& sN,
+ const com::sun::star::uno::Reference<
+ com::sun::star::container::XNameContainer > &rDialog,
+ const com::sun::star::uno::Reference<
+ com::sun::star::lang::XMultiServiceFactory >& rMsf);
+ using OCX_ParentControl::Import; // to not hide the other two import methods
virtual sal_Bool Import( com::sun::star::uno::Reference<
com::sun::star::container::XNameContainer>
&rDialog);
-
- /*sal_uInt8 for sal_uInt8 Word Struct*/
- sal_uInt16 nIdentifier;
- sal_uInt16 nFixedAreaLen;
- sal_uInt8 pBlockFlags[4];
-
- sal_uInt32 nChildrenA;
-
- sal_uInt8 fUnknown1:1;
- sal_uInt8 fEnabled:1;
- sal_uInt8 fLocked:1;
- sal_uInt8 fBackStyle:1;
- sal_uInt8 fUnknown2:4;
-
- sal_uInt8 fUnknown3:8;
-
- sal_uInt8 fUnknown4:7;
- sal_uInt8 fWordWrap:1;
-
- sal_uInt8 fUnknown5:4;
- sal_uInt8 fAutoSize:1;
- sal_uInt8 fUnknown6:3;
-
- sal_uInt32 nCaptionLen;
- sal_uInt16 nVertPos;
- sal_uInt16 nHorzPos;
- sal_uInt8 nMousePointer;
- sal_uInt32 nBorderColor;
- sal_uInt32 nDrawBuffer;
- sal_uInt32 nChildrenB;
- sal_uInt8 nKeepScrollBarsVisible;
- sal_uInt8 nCycle;
- sal_uInt16 nBorderStyle;
- sal_uInt8 nSpecialEffect;
- sal_uInt16 nPicture;
- sal_uInt8 nPictureAlignment;
- sal_uInt8 nPictureSizeMode;
- bool bPictureTiling;
- sal_uInt16 nAccelerator;
- sal_uInt16 nIcon;
- sal_uInt16 fUnknown7;
-
- char *pCaption;
-
- sal_uInt32 nScrollWidth;
- sal_uInt32 nScrollHeight;
- sal_uInt32 nScrollLeft;
- sal_uInt32 nScrollTop;
-
- sal_uInt8 pIconHeader[20];
- sal_uInt32 nIconLen;
- sal_uInt8 *pIcon;
-
- sal_uInt8 pPictureHeader[20];
- sal_uInt32 nPictureLen;
- ::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;
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XComponentContext> mxCtx;
};
@@ -1131,8 +930,6 @@ public:
sal_uInt8 pPictureHeader[20];
sal_uInt32 nPictureLen;
- ::rtl::OUString sImageUrl;
- com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicObject> mxGrfObj;
bool mbTakeFocus;
@@ -1194,7 +991,7 @@ public:
fAutoSize(0),nCaptionLen(0),nVertPos(1),nHorzPos(7),nMousePointer(0),
nBorderColor(0x80000006),nBorderStyle(0),nSpecialEffect(0),
nPicture(0),nAccelerator(0),nIcon(0),pCaption(0),nIconLen(0),pIcon(0),
- nPictureLen(0),pPicture(0)
+ nPictureLen(0)
{
msFormType = rtl::OUString::createFromAscii("com.sun.star.form.component.FixedText");
msDialogType = rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlFixedTextModel");
@@ -1206,7 +1003,6 @@ public:
~OCX_Label() {
if (pCaption) delete[] pCaption;
if (pIcon) delete[] pIcon;
- if (pPicture) delete[] pPicture;
}
sal_Bool Read(SotStorageStream *pS);
@@ -1250,7 +1046,6 @@ public:
sal_uInt8 pPictureHeader[20];
sal_uInt32 nPictureLen;
- sal_uInt8 *pPicture;
static OCX_Control *Create() { return new OCX_Label;}
diff --git a/filter/source/msfilter/msocximex.cxx b/filter/source/msfilter/msocximex.cxx
index bd957d032700..b6e975804ad2 100644
--- a/filter/source/msfilter/msocximex.cxx
+++ b/filter/source/msfilter/msocximex.cxx
@@ -521,7 +521,6 @@ void lclReadCharArray( SvStorageStream& rStrm, char*& rpcCharArr, sal_uInt32 nLe
}
}
-
/** Creates an OUString from a character array created with lclReadCharArray().
The passed parameters must match, that means the length field must be the
@@ -549,6 +548,39 @@ OUString lclCreateOUString( const char* pcCharArr, sal_uInt32 nLenFld )
return svt::BinFilterUtils::CreateOUStringFromUniStringArray( pcCharArr, nBufSize );
}
+void readArrayString( SotStorageStream *pS, std::vector< rtl::OUString >& sStringsOut, sal_Int32 nSize, long nStart )
+{
+ unsigned long nFinish = pS->Tell() + nSize;
+ while ( pS->Tell() < nFinish )
+ {
+ sal_Int32 nStringLen = 0;
+ *pS >> nStringLen;
+ sal_uInt32 nStringSize = lclGetBufferSize( nStringLen );
+ sal_Char* pString = new sal_Char[ nStringSize ];
+ pS->Read( pString, nStringSize );
+ rtl::OUString sString = lclCreateOUString( pString, nStringLen );
+ delete[] pString;
+ sStringsOut.push_back( sString );
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ }
+}
+
+OUString createSubStreamName( const sal_uInt32& subStorageId )
+{
+ static OUString sI = OUString::createFromAscii("i");
+ static OUString sZero = OUString::createFromAscii( "0" );
+ OUStringBuffer buf( 6 );
+ buf.append( sI );
+ // for subStorage id < 10 stream name has leading '0'
+ // eg "i07"
+ if ( subStorageId < 10 )
+ {
+ buf.append( sZero );
+ }
+ buf.append( OUString::valueOf( (sal_Int32)subStorageId ) );
+ return buf.makeStringAndClear();
+}
+
// export ---------------------------------------------------------------------
/** This class implements writing a character array from a Unicode string.
@@ -641,6 +673,44 @@ void SvxOcxString::WriteCharArray( SvStorageStream& rStrm ) const
}
}
+class MultiPageProps
+{
+public:
+ sal_uInt16 nIdentifier; // major & minor version
+ sal_uInt16 nFixedAreaLen; // size of record
+ sal_uInt8 pBlockFlags[4]; // size of record
+ sal_Int32 mnPageCount;
+ sal_Int32 mnID;
+ bool mbEnabled;
+ std::vector< sal_Int32 > mnIDs;
+
+ MultiPageProps();
+ bool Read(SotStorageStream *pS);
+};
+
+MultiPageProps::MultiPageProps() : nIdentifier(0), nFixedAreaLen(0), mnPageCount(0), mnID(0), mbEnabled( true )
+{
+}
+
+bool MultiPageProps::Read(SotStorageStream *pS)
+{
+ *pS >> nIdentifier >> nFixedAreaLen;
+ pS->Read( pBlockFlags, sizeof( pBlockFlags ) );
+ if ( pBlockFlags[ 0 ] & 0x02 )
+ *pS >> mnPageCount;
+ if ( pBlockFlags[ 0 ] & 0x04 )
+ *pS >> mnID;
+ if ( pBlockFlags[ 0 ] & 0x08 )
+ mbEnabled = false;
+ for ( sal_Int32 i=0; i<mnPageCount; ++i )
+ {
+ sal_Int32 nID(0);
+ *pS >> nID;
+ mnIDs.push_back( nID );
+ }
+ return true;
+}
+
const sal_uInt16 USERFORM = (sal_uInt16)0xFF;
const sal_uInt16 STDCONTAINER = (sal_uInt16)0xFE;
@@ -666,48 +736,42 @@ 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 UNKNOWNCTRL = (sal_uInt16)0x7FFF;
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
+// following ActiveX controls are just for reference ( are NOT supported )
+const sal_uInt16 REFEDIT = (sal_uInt16)0x8001;
+const sal_uInt16 CALENDAR = (sal_uInt16)0x8002;
+const sal_uInt16 IMAGECOMBO = (sal_uInt16)0x8003;
+const sal_uInt16 IMAGELIST = (sal_uInt16)0x8004;
+const sal_uInt16 SLIDER = (sal_uInt16)0x8005;
+const sal_uInt16 STATUSBAR = (sal_uInt16)0x8006;
+const sal_uInt16 CHARTSPACE = (sal_uInt16)0x8007;
+
+// A set of common CLSIDs
+// there are to identify the following ActiveX controls ( that appear in the ClassTable records )
// 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,
};
+// 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,
+};
+
// 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[] =
{
@@ -738,238 +802,364 @@ 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
+const sal_uInt8 nSizeOfClsid = sizeof( aProgressID );
-bool lcl_handleActiveXControl( SvStorageStream *pS, sal_uInt16& nTypeID )
+struct ClsIdTypeIDPair
{
- 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 )
+// ClsIdTypeIDPair() : pClsID( NULL ), nTypeID( UNKNOWNCTRL ) {}
+ const sal_uInt8* pClsID;
+ const sal_uInt16 nTypeID;
+};
+
+ClsIdTypeIDPair ClsidList[] = { { aProgressID, PROGRESSBAR },
+// unsupported common activex controls
+#ifdef DEBUG
+ { aRefEditID, REFEDIT },
+ { aCalendarID, CALENDAR },
+ { aImageComboID, IMAGECOMBO },
+ { aImageListID, IMAGELIST },
+ { aSliderID, SLIDER },
+ { aStatusBarID, STATUSBAR },
+ { aChartSpaceID, CHARTSPACE },
+#endif
+};
+
+typedef std::vector< ContainerRecord > ContainerRecordList;
+
+class FormObjectDepthTypeCount
+{
+ public:
+ sal_uInt8 depth;
+ sal_uInt8 TypeOrCount;
+ std::auto_ptr< sal_uInt8 > OptionalType;
+ FormObjectDepthTypeCount() : depth(0), TypeOrCount(0) {}
+ bool Read( SvStorageStream* pS )
+ {
+ *pS >> depth >> TypeOrCount;
+ if ( TypeOrCount & 0x80 )
{
- nTypeID = PROGRESSBAR;
- OSL_TRACE("Found supported ***PROGRESSBAR*** ActiveX control");
- bRes = true;
+ OptionalType.reset( new sal_uInt8 );
+ *pS >> *OptionalType;
}
-#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
+ TypeOrCount = ( TypeOrCount >> 1 );
+ return true;
+ }
+};
+
+class ClassTable
+{
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt32 nContentFlags;
+ sal_uInt16 nClassTableFlags;
+ sal_uInt16 nVarFlags;
+ sal_Int32 nCountOfMethods;
+ sal_Int32 nDispidBind;
+ sal_uInt16 nGetBindIndex;
+ sal_uInt16 nPutBindIndex;
+ sal_uInt16 nBindType;
+ sal_uInt16 nGetValueIndex;
+ sal_uInt16 nPutValueIndex;
+ sal_uInt16 nValueType;
+ sal_uInt32 nDisidRowset;
+ sal_uInt16 nSetRowset;
+ sal_uInt8 pClsId[16];
+ sal_uInt8 pDispEvent[16];
+ sal_uInt8 pDefaultProg[16];
+ sal_uInt16 nTypeId;
+public:
+ ClassTable() : nIdentifier( 0 )
+ ,nFixedAreaLen( 0 )
+ ,nContentFlags(0)
+ ,nClassTableFlags(0)
+ ,nVarFlags(0)
+ ,nCountOfMethods(0)
+ ,nDispidBind(0)
+ ,nGetBindIndex(0)
+ ,nPutBindIndex(0)
+ ,nBindType(0)
+ ,nGetValueIndex(0)
+ ,nPutValueIndex(0)
+ ,nValueType(0)
+ ,nDisidRowset(0)
+ ,nSetRowset(0)
+ ,nTypeId(UNKNOWNCTRL)
+
+ {
+ memset( pClsId, 0, sizeof( pClsId ) );
+ memset( pDispEvent, 0, sizeof( pDispEvent ) );
+ memset( pDefaultProg, 0, sizeof( pDefaultProg ) );
+ }
+ bool Read( SvStorageStream* pS )
+ {
+ long nStartPos = pS->Tell();
+ *pS >> nIdentifier >> nFixedAreaLen >> nContentFlags;
+ bool bClsID( false );
+ bool bDispEvent( false );
+ bool bDefaultProg( false );
+ if ( nContentFlags & 0x00000001 )
+ bClsID = true;
+ if ( nContentFlags & 0x00000002 )
+ bDispEvent = true;
+// if ( nContentFlags & 0x00000004 ) ' not set should be 0
+ if ( nContentFlags & 0x00000008 )
+ bDefaultProg = true;
+ if ( nContentFlags & 0x00000010 )
+ *pS >> nClassTableFlags >> nVarFlags;
+ if ( nContentFlags & 0x00000020 )
+ *pS >> nCountOfMethods;
+ if ( nContentFlags & 0x00000040 )
+ *pS >> nDispidBind;
+ if ( nContentFlags & 0x00000080 )
+ *pS >> nGetBindIndex;
+ if ( nContentFlags & 0x00000100 )
+ *pS >> nPutBindIndex;
+ if ( nContentFlags & 0x00000200 )
+ *pS >> nBindType;
+ if ( nContentFlags & 0x00000400 )
+ *pS >> nGetValueIndex;
+ if ( nContentFlags & 0x00000800 )
+ *pS >> nPutValueIndex;
+ if ( nContentFlags & 0x00001000 )
+ *pS >> nValueType;
+ if ( nContentFlags & 0x00002000 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> nDisidRowset;
+ }
+ if ( nContentFlags & 0x00004000 )
+ *pS >> nSetRowset;
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ // Extra Block
+ if ( bClsID )
+ pS->Read( pClsId, sizeof( pClsId ) );
+ if ( bDispEvent )
+ pS->Read( pDispEvent, sizeof( pDispEvent ) );
+ if ( bDefaultProg )
+ pS->Read( pDefaultProg, sizeof( pDefaultProg ) );
+
+ sal_Int32 nNumIds = sizeof( ClsidList ) / sizeof( ClsidList[0] );
+
+ if ( bClsID )
{
- OSL_TRACE("Unknown activeX ID !");
+ for ( sal_Int32 index = 0; index < nNumIds; ++index )
+ {
+ if ( memcmp( pClsId, ClsidList[ index ].pClsID, nSizeOfClsid ) == 0 )
+ {
+ nTypeId = ClsidList[ index ].nTypeID;
+ OSL_TRACE( "... found activex control ClsidList[ %d ] and have given it TypeIdent 0x%x", index, nTypeId );
+ }
+ }
}
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ return true;
}
- return bRes;
-}
-typedef std::vector< ContainerRecord > ContainerRecordList;
+ sal_uInt16 getTypeId() { return nTypeId; }
+};
-class ContainerRecReader
+class OleSiteConcreteControl
{
- public:
+ sal_uInt16 nIdentifier;
+ sal_uInt16 nFixedAreaLen;
+ sal_uInt32 nContentFlags;
+public:
+ OleSiteConcreteControl() : nIdentifier( 0 ), nFixedAreaLen( 0 ), nContentFlags(0) {}
+ bool Read( ContainerRecord& rec, SvStorageStream* pS )
+ {
+ long nStartPos = pS->Tell();
+ *pS >> nIdentifier >> nFixedAreaLen >> nContentFlags;
+
+ bool bPosition( false );
+
+ sal_uInt32 nNameLen = 0;
+ // length of control name
+ if ( nContentFlags & 0x00000001 )
+ *pS >> nNameLen;
+ // length of control tag
+ sal_uInt32 nTagLen = 0;
+ if( nContentFlags & 0x00000002 )
+ *pS >> nTagLen;
+ // substorage id for frames
+ if( nContentFlags & 0x00000004 )
+ *pS >> rec.nSubStorageId;
+ // help-context id
+ if( nContentFlags & 0x00000008 )
+ pS->SeekRel( 4 );
+ // option flags
+ if( nContentFlags & 0x00000010 )
+ {
+ sal_uInt32 nBitFlags = 0;
+ *pS >> nBitFlags;
+ rec.bVisible = ( nBitFlags & 0x02 );
+ rec.bTabStop = ( nBitFlags & 0x01 );
+ }
+ // substream size
+ if( nContentFlags & 0x00000020 )
+ *pS >> rec.nSubStreamLen;
+ // tabstop position
+ if( nContentFlags & 0x00000040 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 2 );
+ *pS >> rec.nTabPos;
+ }
+ // control type
+ if( nContentFlags & 0x00000080 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 2 );
+ *pS >> rec.nTypeIdent;
+ }
+ if( nContentFlags & 0x00000100 )
+ bPosition = true;
+ sal_Int16 nGroupId = 0;
+ if( nContentFlags & 0x00000200 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 2 );
+ *pS >> nGroupId;
+ }
- virtual ~ContainerRecReader() {}
+ // length of infotip
+ sal_uInt32 nTipLen = 0;
+ if( nContentFlags & 0x00000800 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> nTipLen;
+ }
+ sal_uInt32 nCntrlIdLen = 0;
+ if( nContentFlags & 0x00001000 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> nCntrlIdLen;
+ }
- virtual bool Read( OCX_ContainerControl* pContainerControl, SvStorageStream *pS)
- {
- *pS >> nNoRecords;
- *pS >> nTotalLen;
+ // length of control source name
+ sal_uInt32 nCtrlSrcLen = 0;
+ if( nContentFlags & 0x00002000 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> nCtrlSrcLen;
+ }
- if ( isMultiPage )
+ // length of row source name
+ sal_uInt32 nRowSrcLen = 0;
+ if( nContentFlags & 0x00004000 )
{
- if ( !handleMultiPageHdr( pS ) )
- {
- return false;
- }
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> nRowSrcLen;
}
- else
+
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ // control name
+ sal_Char* pName = 0;
+ sal_uInt32 nNameBufSize = lclGetBufferSize( nNameLen );
+ if( nNameBufSize > 0 )
{
- if ( !handleStandardHdr( pS ) )
- {
- return false;
- }
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pName = new char[ nNameBufSize ];
+ pS->Read( pName, nNameBufSize );
+ }
+ // control tag
+ sal_uInt32 nTagBufSize = lclGetBufferSize( nTagLen );
+ if( nTagBufSize > 0 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pS->SeekRel( nTagBufSize );
}
- records.clear();
- for (sal_uInt32 nRecord = 0; nRecord < nNoRecords; ++nRecord)
+ // control position
+ if( bPosition )
{
- // DR #134146# redo loading of FrameChild data
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ *pS >> rec.nLeft >> rec.nTop;
+ }
- ContainerRecord rec;
+ // control infotip
+ sal_uInt32 nTipBufSize = lclGetBufferSize( nTipLen );
+ if( nTipBufSize > 0 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ std::auto_ptr< sal_Char > pTipName;
+ pTipName.reset( new sal_Char[ nTipBufSize ] );
+ pS->Read( pTipName.get(), nTipBufSize );
+ rec.controlTip = lclCreateOUString( pTipName.get(), nTipLen );
+ }
+ // control id
+ sal_uInt32 nCntrlIdSize = lclGetBufferSize( nCntrlIdLen );
+ if( nCntrlIdSize > 0 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ pS->SeekRel( nCntrlIdSize );
+ }
+ // control source name
+ sal_uInt32 nCtrlSrcBufSize = lclGetBufferSize( nCtrlSrcLen );
+ if( nCtrlSrcBufSize > 0 )
+ {
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ std::vector< sal_Char > pCtrlSrcName( nCtrlSrcBufSize );
+ pS->Read( &pCtrlSrcName[0], nCtrlSrcBufSize );
+ rec.sCtrlSource = lclCreateOUString( &pCtrlSrcName[0], 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 );
+ std::vector< sal_Char > pRowSrcName( nRowSrcBufSize );
+ pS->Read( &pRowSrcName[0], nRowSrcBufSize );
+ rec.sRowSource = lclCreateOUString( &pRowSrcName[0], nRowSrcLen );
+ OSL_TRACE("*** *** *** RowSourceName -> %s ", rtl::OUStringToOString( rec.sRowSource, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
- // record header
- sal_uInt16 nId, nSize;
- *pS >> nId >> nSize;
- sal_Size nStartPos = pS->Tell();
-
- // content flags
- sal_uInt32 nContentFlags;
- *pS >> nContentFlags;
-
- // length of control name
- sal_uInt32 nNameLen = 0;
- if( nContentFlags & 0x00000001 )
- *pS >> nNameLen;
- // length of control tag
- sal_uInt32 nTagLen = 0;
- if( nContentFlags & 0x00000002 )
- *pS >> nTagLen;
- // substorage id for frames
- if( nContentFlags & 0x00000004 )
- *pS >> rec.nSubStorageId;
- // help-context id
- if( nContentFlags & 0x00000008 )
- pS->SeekRel( 4 );
- // option flags
- if( nContentFlags & 0x00000010 )
- {
- sal_uInt32 nBitFlags = 0;
- *pS >> nBitFlags;
- rec.bVisible = ( ( nBitFlags & 0x02 ) == 0x02 );
- }
- // substream size
- if( nContentFlags & 0x00000020 )
- *pS >> rec.nSubStreamLen;
- // tabstop position
- if( nContentFlags & 0x00000040 )
- *pS >> rec.nTabPos;
- // 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 )
- {
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- *pS >> nTipLen;
- }
+ ReadAlign( pS, pS->Tell() - nStartPos, 4 );
+ rec.cName = lclCreateOUString(pName, nNameLen);
+ delete[] pName;
+ return true;
+ }
+};
- sal_uInt32 nCntrlIdLen = 0;
- if( nContentFlags & 0x00001000 )
- *pS >> nCntrlIdLen;
+class ContainerRecReader
+{
+ public:
- // length of control source name
- sal_uInt32 nCtrlSrcLen = 0;
- if( nContentFlags & 0x00002000 )
- {
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- *pS >> nCtrlSrcLen;
- }
+ virtual ~ContainerRecReader() {}
- // length of row source name
- sal_uInt32 nRowSrcLen = 0;
- if( nContentFlags & 0x00004000 )
- {
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- *pS >> nRowSrcLen;
- }
+ virtual bool Read( OCX_ParentControl* pContainerControl, SvStorageStream *pS, std::vector< ClassTable >& rSiteClassInfo )
+ {
+ *pS >> nNoRecords;
+ *pS >> nTotalLen;
+ long nStart = pS->Tell();
+ for ( sal_uInt32 nSite = 0; nSite < nNoRecords; )
+ {
+ FormObjectDepthTypeCount siteAndDepth;
+ siteAndDepth.Read( pS );
+ nSite += ( siteAndDepth.OptionalType.get() ? siteAndDepth.TypeOrCount : 1 );
+ }
- // control name
- sal_Char* pName = 0;
- sal_uInt32 nNameBufSize = lclGetBufferSize( nNameLen );
- if( nNameBufSize > 0 )
- {
- pName = new char[ nNameBufSize ];
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- pS->Read( pName, nNameBufSize );
- }
- // control tag
- sal_uInt32 nTagBufSize = lclGetBufferSize( nTagLen );
- if( nTagBufSize > 0 )
- {
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- pS->SeekRel( nTagBufSize );
- }
+ ReadAlign(pS, pS->Tell() - nStart, 4);
- // control position
- if( nContentFlags & 0x00000100 )
- {
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- *pS >> rec.nLeft >> rec.nTop;
- }
+ for (sal_uInt32 nRecord = 0; nRecord < nNoRecords; ++nRecord)
+ {
- // control infotip
- sal_uInt32 nTipBufSize = lclGetBufferSize( nTipLen );
- if( nTipBufSize > 0 )
- {
- std::auto_ptr< sal_Char > pTipName;
- pTipName.reset( new sal_Char[ nTipBufSize ] );
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- pS->Read( pTipName.get(), nTipBufSize );
- rec.controlTip = lclCreateOUString( pTipName.get(), nTipLen );
- }
- // control id
- sal_uInt32 nCntrlIdSize = lclGetBufferSize( nCntrlIdLen );
- if( nCntrlIdSize > 0 )
- {
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- pS->SeekRel( nCntrlIdSize );
- }
- // control source name
- sal_uInt32 nCtrlSrcBufSize = lclGetBufferSize( nCtrlSrcLen );
- if( nCtrlSrcBufSize > 0 )
- {
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- 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 )
+ ContainerRecord rec;
+
+ OleSiteConcreteControl site;
+ site.Read( rec, pS );
+ if ( rec.nTypeIdent >= ( UNKNOWNCTRL + 1 ) )
{
- ReadAlign( pS, pS->Tell() - nStartPos, 4 );
- 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() );
+ sal_uInt16 nIndex = rec.nTypeIdent - ( UNKNOWNCTRL + 1 );
+ if ( nIndex < rSiteClassInfo.size() )
+ rec.nTypeIdent = rSiteClassInfo[ nIndex ].getTypeId();
}
-
- // seek to end of data
- pS->Seek( nStartPos + nSize );
-
- rec.cName = lclCreateOUString(pName, nNameLen);
- delete[] pName;
-
OCX_Control* pControl = NULL;
+ OSL_TRACE("** About to create control of type 0x%x with name %s from rec", rec.nTypeIdent, rtl::OUStringToOString( rec.cName, RTL_TEXTENCODING_UTF8 ).getStr() );
if( pContainerControl->createFromContainerRecord( rec, pControl ) &&
pControl )
{
// propagate doc shell from parent
pControl->pDocSh = pContainerControl->pDocSh;
pContainerControl->ProcessControl( pControl, pS, rec );
+
}
else if ( rec.nTypeIdent & 0x8000 )
{
@@ -987,90 +1177,12 @@ class ContainerRecReader
return true;
}
+ ContainerRecReader():nNoRecords(0), nTotalLen(0){}
protected:
- ContainerRecReader() : isMultiPage(false){}
- bool isMultiPage;
sal_uInt32 nNoRecords;
sal_uInt32 nTotalLen;
private:
- bool handleStandardHdr( SvStorageStream* pS )
- {
- 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;
- }
-
- bool handleMultiPageHdr( SvStorageStream* pS )
- {
- sal_uInt32 nUnknown_32b; // unknown 32 bit structure, flags ?
- sal_uInt16 nUnknown_16b; // unknown 16 bit structure
- sal_uInt16 nMysteryLen; // lenght of unknown sub record
-
- *pS >> nUnknown_32b;
- *pS >> nUnknown_16b;
- *pS >> nMysteryLen;
-
- pS->SeekRel( nMysteryLen );
- return true;
- }
- ContainerRecordList records;
-};
-
-class StdContainerRecReader : public ContainerRecReader
-{
- public:
- StdContainerRecReader(){}
-};
-
-class MultiPageContainerRecReader : public ContainerRecReader
-{
- public:
- MultiPageContainerRecReader()
- {
- // NP ( 27-01-05 )
- // Strictly speaking this approach shouldn't be necessary.
- // It should be possible to have a common routine read the
- // container record array and by examining the flags present in
- // the record to determine we expect to read or not.
- // In this case for a MultPage control there is no Top or Left
- // values in the control record array, however time contraints
- // and associated risk prevent further investigation of this
- // at the moment.
- // similar situation exists for the start of the container record
- // which in the case of the MultiPage is different from
- // UserForm & Frame ( the other containers )
-
- isMultiPage = true; // tell the base class skip
- }
-};
-
-class ContainerRecordReaderFac
-{
- public:
- static ContainerRecReader* instance( sal_uInt32 containerType )
- {
- switch( containerType )
- {
- case PAGE:
- case FRAME:
- case USERFORM:
- case STDCONTAINER:
- return new StdContainerRecReader();
- case MULTIPAGE:
- return new MultiPageContainerRecReader();
- default:
- DBG_ERROR("Illegal container type for factory");
- return NULL;
- }
- }
- private:
- ContainerRecordReaderFac();
};
} // namespace
@@ -1273,6 +1385,7 @@ sal_Bool OCX_Control::Import(uno::Reference<container::XNameContainer> &rDialog
}
uno::Reference<beans::XPropertySet> xPropSet(xCreate, uno::UNO_QUERY);
+
if (!xPropSet.is())
return sal_False;
@@ -2202,6 +2315,12 @@ sal_Bool OCX_TextBox::Import(com::sun::star::uno::Reference<
}
}
+ if ( sImageUrl.getLength() )
+ {
+ aTmp <<= sImageUrl;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ImageURL"), aTmp);
+ }
+
aFontData.Import(rPropSet);
return sal_True;
}
@@ -3648,8 +3767,15 @@ sal_Bool OCX_Label::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 );
}
if (nIcon)
{
@@ -3669,325 +3795,61 @@ TypeName::TypeName(sal_Char *pName, sal_uInt32 nStoreId, sal_uInt32 nLen, sal_uI
{
}
-OCX_ContainerControl::OCX_ContainerControl( SotStorageRef& parent,
- const ::rtl::OUString& storageName,
- const ::rtl::OUString& sN,
- const uno::Reference< container::XNameContainer > &rParent,
- OCX_Control* pParent ) :
- OCX_Control(sN, pParent), mxParent(rParent), nNoRecords(0), nTotalLen(0), containerType( STDCONTAINER )
-{
-
- mContainerStorage = parent->OpenSotStorage(storageName,
- STREAM_READWRITE |
- STREAM_NOCREATE |
- STREAM_SHARE_DENYALL);
- mContainerStream = mContainerStorage->OpenSotStream(
- String(RTL_CONSTASCII_STRINGPARAM("f"),
- RTL_TEXTENCODING_MS_1252),
- STREAM_STD_READ | STREAM_NOCREATE);
- mContainedControlsStream = mContainerStorage->OpenSotStream( String(RTL_CONSTASCII_STRINGPARAM("o"),
- RTL_TEXTENCODING_MS_1252),
- STREAM_STD_READ | STREAM_NOCREATE);
-}
-OCX_ContainerControl::~OCX_ContainerControl()
-{
- CtrlIterator aEnd = mpControls.end();
- for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
- {
- delete *aIter;
- }
-}
-
-// Really import should receive the parent e.g. a Userform, Frame or Multi Page
-// and call import on its containees with itself ( up-called from
-// the base class ) but... the reality is we have no containment model
-// so we make sure rPropSet is always the parent Dialog
-
-sal_Bool OCX_ContainerControl::Import(uno::Reference<beans::XPropertySet>& /* rProps */ )
-{
- if ( !mxParent.is() )
- {
- return sal_False;
- }
- CtrlIterator aEnd = mpControls.end();
-// int count = 0;
- for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
- {
- if ( !(*aIter)->Import( mxParent ) )
- {
- return sal_False;
- }
- }
- return sal_True;
-}
-
-OUString OCX_ContainerControl::createSubStreamName( const sal_uInt32& subStorageId )
-{
- static OUString sI = OUString::createFromAscii("i");
- static OUString sZero = OUString::createFromAscii( "0" );
- OUStringBuffer buf( 6 );
- buf.append( sI );
- // for subStorage id < 10 stream name has leading '0'
- // eg "i07"
- if ( subStorageId < 10 )
- {
- buf.append( sZero );
- }
- buf.append( OUString::valueOf( (sal_Int32)subStorageId ) );
- return buf.makeStringAndClear();
-}
-
-
-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:
- pControl = new OCX_CommandButton;
- break;
- case LABEL:
- pControl = new OCX_UserFormLabel(this);
- break;
- case TEXTBOX:
- pControl = new OCX_TextBox;
- break;
- case LISTBOX:
- pControl = new OCX_ListBox;
- break;
- case COMBOBOX:
- pControl = new OCX_ComboBox;
- break;
- case CHECKBOX:
- pControl = new OCX_CheckBox;
- break;
- case OPTIONBUTTON:
- pControl = new OCX_OptionButton;
- break;
- case TOGGLEBUTTON:
- pControl = new OCX_ToggleButton;
- break;
- case IMAGE: //Image
- {
- pControl = new OCX_Image;
- break;
- }
- case PAGE: // Page
- {
- OUString sMSStore = createSubStreamName( record.nSubStorageId );
- pControl = new OCX_Page(mContainerStorage, sMSStore,
- record.cName, mxParent, this);
- break;
- }
- case MULTIPAGE: // MultiPage
- {
- OUString sMSStore = createSubStreamName( record.nSubStorageId );
- pControl = new OCX_MultiPage( mContainerStorage, sMSStore,
- record.cName, mxParent, this);
- break;
- }
- case FRAME: //Frame
- {
- OUString sFrameStore = createSubStreamName( record.nSubStorageId );
- pControl = new OCX_Frame(mContainerStorage, sFrameStore,
- record.cName, mxParent, this);
-
- break;
- }
- case SPINBUTTON: //SpinButton
- {
- pControl = new OCX_SpinButton;
- break;
- }
- case TABSTRIP: //TabStrip
- {
- pControl = new OCX_TabStrip;
- break;
- }
- case SCROLLBAR: //ScrollBar
- pControl = new OCX_ScrollBar;
- break;
- case PROGRESSBAR: //ProgressBar Active X control
- pControl = new OCX_ProgressBar;
- break;
- default:
- OSL_TRACE( "**** Unknown control 0x%x", record.nTypeIdent );
- DBG_ERROR( "Unknown control");
- return false;
- }
- pControl->sName = record.cName;
- return true;
-}
-
-
-void addSeperator( std::vector< OCX_Control* >& dest )
-{
- OCX_Control* seperator = new OCX_CommandButton;
- seperator->SetInDialog(true);
- seperator->sName = C2S("GroupSeperator");
- dest.push_back( seperator );
-}
-
-void addRButtons( 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 );
- }
-}
-
-void OCX_ContainerControl::ProcessControl(OCX_Control* pControl,SvStorageStream* /* pS */, ContainerRecord& rec )
-{
- SotStorageStreamRef oStream = mContainedControlsStream;
-
- // can insert into OO Dialog (e.g is this a supported dialog control)??
- if ( rec.nTypeIdent == TABSTRIP )
- {
- // skip the record in the stream, discard the control
- oStream->SeekRel( rec.nSubStreamLen );
- delete pControl;
- }
- else
- {
- // A container control needs to read the f stream in
- // the folder ( substorage ) associated with this control
- switch ( rec.nTypeIdent )
- {
- 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
- pControl->mnTop = rec.nTop + mnTop;
- pControl->mnLeft = rec.nLeft + mnLeft;
- // MS tabIndex, pretty useless in OpenOffice land
- // as tab indexes in MS are relative to parent container.
- // However we need this value in order to set
- // OpenOffice tab indices in a sensible way to
- // reflect the ms tabbing from orig MS UserForm, see below
- pControl->mnTabPos = rec.nTabPos;
- pControl->SetInDialog(true);
- pControl->mbVisible = rec.bVisible;
- if ( mnStep )
- {
- // If the container has a step then it should be
- // applied to all containees
- pControl->mnStep = mnStep;
- }
- pControl->msParentName = sName;
-
- // #117490# DR: container records provide size of substream, use it here...
-
- // remember initial position to set correct stream position
- ULONG nStrmPos = oStream->Tell();
- // import control, may return with invalid stream position
- pControl->FullRead(oStream);
- // set stream to position behind substream of this control
- oStream->Seek( nStrmPos + rec.nSubStreamLen );
-
- mpControls.push_back( pControl );
- }
-}
-
-sal_Bool OCX_ContainerControl::Read(SvStorageStream *pS)
-{
-
- if ( mpParent )
- {
- mnBackColor = mpParent->mnBackColor;
- }
-
- std::auto_ptr< ContainerRecReader > reader (
- ContainerRecordReaderFac::instance( containerType ) );
-
- reader->Read( this, pS );
- // Need to honour the MS Tab Indexes. However MS tab indexes are
- // relative to parent, this hack sorts the controls in each container
- // based on the ms tab indexes. When import is called we create the
- // controls in Open/Star office based on the order of the tab indexes,
- // 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() );
- return true;
-}
-
OCX_MultiPage::OCX_MultiPage( SotStorageRef& parent,
const ::rtl::OUString& storageName,
const ::rtl::OUString& sN,
const uno::Reference< container::XNameContainer > &rDialog,
OCX_Control* pParent):
- OCX_ContainerControl(parent, storageName, sN, rDialog, pParent ), fUnknown1(0), fEnabled(1),
- fLocked(0), fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0),
- nVertPos(1), nHorzPos(7), nMousePointer(0), nBorderColor(0x80000012),
- 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), nIconLen(0), pIcon(0), nPictureLen(0),
- pPicture(0)
-{
- //msDialogType = C2U("NotSupported");
+ OCX_ParentControl(parent, storageName, sN, rDialog, pParent ), bHasTabs( true )
+
+{
msDialogType = C2U("com.sun.star.awt.UnoMultiPageModel");
mnForeColor = 0x80000012L,
mnBackColor = 0x8000000FL;
bSetInDialog = true;// UserForm control only
aFontData.SetHasAlign(TRUE);
- containerType = MULTIPAGE;
- mnCurrentPageStep = 0;
+ nActiveTab = 0;
+ // open up the 'x' stream
+ mXStream = mContainerStorage->OpenSotStream(
+ String(RTL_CONSTASCII_STRINGPARAM("x"),
+ RTL_TEXTENCODING_MS_1252),
+ STREAM_STD_READ | STREAM_NOCREATE);
}
void OCX_MultiPage::ProcessControl(OCX_Control* pControl, SvStorageStream* /* pS */, ContainerRecord& rec )
{
SotStorageStreamRef oStream = mContainedControlsStream;
- OCX_Page *pPage = NULL;
- if ( rec.nTypeIdent == PAGE )
- pPage = static_cast< OCX_Page* >( pControl );
- if ( pPage != NULL )
+ if ( rec.nTypeIdent == TABSTRIP )
{
- pPage->mnStep = ++mnCurrentPageStep;
-
- pPage->mnTop = mnTop;// move these to Page::import ?
- pPage->mnLeft = mnLeft;
- pPage->mnBackColor = mnBackColor;
-
- oStream = pPage->getContainerStream();;
- // Position of controls is relative to pos of this MuliPage
- // Control
- pPage->FullRead( oStream );
+ // TabStrip reads the 'o' stream
+ OCX_TabStrip oTabStrip;
+ oTabStrip.sName = C2S("FromMultiPage-o");
+ oTabStrip.Read( mContainedControlsStream );
+ sCaptions = oTabStrip.msItems;
+ bHasTabs = oTabStrip.bHasTabs;
+ nHeight = oTabStrip.nHeight;
+ nWidth = oTabStrip.nWidth;
+ }
+ else if ( rec.nTypeIdent == PAGE )
+ {
+ OCX_Page *pPage = NULL;
+ pPage = static_cast< OCX_Page* >( pControl );
+ if ( pPage != NULL )
+ {
+ oStream = pPage->getContainerStream();;
+ // Position of controls is relative to pos of this MuliPage
+ // Control
+ pPage->FullRead( oStream );
+ // nWidth & nHeight seem to screw up multipage control
+ pPage->nWidth = 0;
+ pPage->nHeight = 0;
+ pPage->mnBackColor = mnBackColor;
+
+ mpControls.push_back( pPage );
+ idToPage[ pPage->mnID ] = pPage;
+ }
- mpControls.push_back( pPage );
}
else
{
@@ -4001,110 +3863,78 @@ sal_Bool OCX_MultiPage::Read(SvStorageStream *pS)
{
// Unlike the other containers e.g. UserForm & Frame
// the o stream is does not contain info for the contained controls
- // ( e.g. the pages themselves ) but seems to be for the MultiPage
- // itself - need to check this in more detail
-
- // For the moment skip read of the MultiPage specific properties
- // not much point reading these as we can't display the multi page
- // control or in fact any sort of tabbed layout, best we can do is
- // import just the contained controls of the individual pages
- // Note: the record skipped below ( does not contain the expected
- // info on this control, that seems to be contained in the o stream,
- // see comment above)
+ // 'o' stream contains a tabstrip control
+ // 'f' stream as usual ( info about the containees )
+ // '01..09' ( etc. ) these streams contain the page controls
+ // 'x' stream, this contains an array of properties for each page followed
+ // by a set of properties for the multipage control itself
+
+ // read the 'f' stream
+ OCX_ParentControl::Read(pS);
+
+ // Read the 'x' stream
+ // consists of
+ // a) nTabs + 1 PageProperties ( which are little use to us )
+ // => skip
+ // b) a MutliPageProperty ( which contains at least the page count and
+ // IDs of the pages ( and order ) - useful for associating correct page
+ // with correct tab
+
+
OCX_Control skip(C2S("Dummy"));
- skip.Read( pS );
- mnCurrentPageStep = mnStep; //( set step of of pages relative to step
- //of this MultiPage ( e.g. emulate containment )
- return OCX_ContainerControl::Read(pS);
+ sal_Int32 nPagePropsToRead = sCaptions.size() + 1;
+ for ( sal_Int32 page = 0; page < nPagePropsToRead; ++page )
+ skip.Read( mXStream );
+ MultiPageProps multiPage;
+ multiPage.Read( mXStream );
+ mPageIds = multiPage.mnIDs;
+ return true;
}
sal_Bool OCX_MultiPage::Import(com::sun::star::uno::Reference<
com::sun::star::beans::XPropertySet> &rPropSet)
{
- OCX_ContainerControl::Import( rPropSet );
- return sal_True;
-}
-
-sal_Bool OCX_MultiPage::Import(com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer>
- &rDialog)
-{
- uno::Reference<beans::XPropertySet> xPropSet( rDialog, uno::UNO_QUERY );
-
- // Although MultiPage is not represeted by a "real" control we still
- // need to propagate the backcolor of this logical parent
- // ( the dialog or Frame or whatever ) to the children of this control.
- // For example the controls contained in the Page of a
- // MultiPage control use the parents backcolor ( e,g,
- // Pages backcolor ) when trying to fake transparency
- mnBackColor = mpParent->mnBackColor;
-
- 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
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), aTmp);
+ if ( !bHasTabs )
+ rPropSet->setPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Decoration")), uno::makeAny( sal_False ) );
+ aTmp <<= ImportColor(mnBackColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+ // apply caption/titles to pages
+ std::vector<sal_Int32>::iterator itCtrlId = mPageIds.begin();
+ std::vector<sal_Int32>::iterator itCtrlId_end = mPageIds.end();
+ std::vector< rtl::OUString >::iterator itCaption = sCaptions.begin();
+ mpControls.clear();
+ // need to sort the controls according to the order of the ids
+ for ( sal_Int32 index = 1 ; ( sCaptions.size() == idToPage.size() ) && itCtrlId != itCtrlId_end; ++itCtrlId, ++itCaption, ++index )
+ {
+ std::hash_map< sal_Int32, OCX_Page* >::iterator it = idToPage.find( *itCtrlId );
+ if ( it != idToPage.end() )
{
- // 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");
+ it->second->msTitle = *itCaption;
+ if ( it->second->mbVisible )
+ nActiveTab = index;
+ mpControls.push_back( it->second );
- // 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 );
}
- OSL_TRACE("*** Major problem, no dialog to add controls to ");
- DBG_ERROR(" Major problem, no dialog to add controls to ");
- return false;
-}
-
+ OCX_ParentControl::Import( rPropSet );
+ rPropSet->setPropertyValue( WW8_ASCII2STR("MultiPageValue"), uno::makeAny( nActiveTab ));
+ return sal_True;
+}
OCX_Page::OCX_Page( SotStorageRef& parent,
- const ::rtl::OUString& storageName,
+ sal_Int32 nId,
const ::rtl::OUString& sN,
const uno::Reference< container::XNameContainer > &rDialog,
OCX_Control* pParent):
- OCX_ContainerControl(parent, storageName, sN, rDialog, pParent ),
- fUnknown1(0), fEnabled(1), fLocked(0),
- fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0), nVertPos(1),
- nHorzPos(7), nMousePointer(0), nBorderColor(0x80000012),
- 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), nIconLen(0), pIcon(0), nPictureLen(0),
- pPicture(0)
-{
- msDialogType = C2U("NotSupported");
+ OCX_ParentControl(parent, createSubStreamName( nId ), sN, rDialog, pParent ), mnID( nId )
+{
+ msDialogType = C2U("com.sun.star.awt.UnoPageModel");
mnForeColor = 0x80000012,
mnBackColor = 0x8000000F,
bSetInDialog = true;// UserForm control only
@@ -4114,65 +3944,35 @@ OCX_Page::OCX_Page( SotStorageRef& parent,
sal_Bool OCX_Page::Read(SvStorageStream *pS)
{
- long nStart = pS->Tell();
- *pS >> nIdentifier;
- DBG_ASSERT(0x400==nIdentifier,
- "A control that has a different identifier");
- *pS >> nFixedAreaLen;
- pS->Read(pBlockFlags,4);
-
- pS->SeekRel( nFixedAreaLen - sizeof( pBlockFlags ) );
-
- ReadAlign( pS, pS->Tell() - nStart, 4);
-
- if (pBlockFlags[2] & 0x10)
- {
- //Font Stuff..
- pS->SeekRel(0x1a);
- sal_uInt8 nFontLen;
- *pS >> nFontLen;
- pS->SeekRel(nFontLen);
- }
- return OCX_ContainerControl::Read(pS);
-
+ return OCX_ParentControl::Read(pS);
}
sal_Bool OCX_Page::Import(com::sun::star::uno::Reference<
- com::sun::star::container::XNameContainer>
- &rDialog)
+ com::sun::star::beans::XPropertySet>
+ &rPropSet)
{
+ uno::Any aTmp(&sName,getCppuType((OUString *)0));
+ rPropSet->setPropertyValue(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), aTmp);
+
+ if (msTitle.getLength())
+ rPropSet->setPropertyValue( WW8_ASCII2STR("Title"), uno::makeAny( msTitle ) );
+
+ aTmp <<= ImportColor(mnBackColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
+ // Calls import on contained controls
+ OCX_ParentControl::Import( rPropSet );
+ return sal_True;
- uno::Reference<beans::XPropertySet> xPropSet( rDialog, uno::UNO_QUERY );
- if ( xPropSet.is() )
- {
- // apply Step to contained controls
- CtrlIterator aEnd = mpControls.end();
- for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
- {
- (*aIter)->mnStep = mnStep;
- }
- // Calls import on contained pages
- return OCX_ContainerControl::Import( xPropSet );
- }
- OSL_TRACE("*** Major problem, no dialog to add controls to ");
- DBG_ERROR("*** Major problem, no dialog to add controls to ");
- return sal_False;
}
OCX_Frame::OCX_Frame( SotStorageRef& parent,
const ::rtl::OUString& storageName,
const ::rtl::OUString& sN,
- const uno::Reference< container::XNameContainer > &rDialog, OCX_Control* pParent):
- OCX_ContainerControl(parent, storageName, sN, rDialog, pParent ),fUnknown1(0),fEnabled(1), fLocked(0),
- fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0), nVertPos(1),
- nHorzPos(7), nMousePointer(0), nBorderColor(0x80000012),
- 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)
-{
- msDialogType = C2U("com.sun.star.awt.UnoControlGroupBoxModel");
+ const uno::Reference< container::XNameContainer > &rDialog, OCX_Control* pParent): OCX_ParentControl(parent, storageName, sN, rDialog, pParent )
+{
+ msDialogType = C2U("com.sun.star.awt.UnoFrameModel");
mnForeColor = 0x80000012;
mnBackColor = 0x8000000F;
bSetInDialog = true;// UserForm control only
@@ -4182,159 +3982,7 @@ OCX_Frame::OCX_Frame( SotStorageRef& parent,
sal_Bool OCX_Frame::Read(SvStorageStream *pS)
{
- long nStart = pS->Tell();
- *pS >> nIdentifier;
- DBG_ASSERT(0x400==nIdentifier,
- "A control that has a different identifier");
- *pS >> nFixedAreaLen;
- pS->Read(pBlockFlags,4);
-
- if (pBlockFlags[0] & 0x01)
- {
- DBG_ASSERT(!this, "ARSE");
- }
- if (pBlockFlags[0] & 0x02)
- *pS >> mnBackColor;
- if (pBlockFlags[0] & 0x04)
- *pS >> mnForeColor;
- if (pBlockFlags[0] & 0x08)
- *pS >> fUnknown1;
- if (pBlockFlags[0] & 0x40)
- {
- sal_uInt8 nTemp;
- *pS >> nTemp;
- fEnabled = (nTemp&0x04)>>2;
- fBackStyle = (nTemp&0x08)>>3;
- *pS >> nTemp;
- *pS >> nTemp;
- fWordWrap = (nTemp&0x80)>>7;
- *pS >> nTemp;
- fAutoSize = (nTemp&0x10)>>4;
- }
- if (pBlockFlags[0] & 0x80)
- {
- *pS >> nBorderStyle;
- }
-
- ReadAlign(pS, pS->Tell() - nStart, 4);
-
- if (pBlockFlags[1] & 0x01)
- *pS >> nMousePointer;
- if (pBlockFlags[1] & 0x02)
- *pS >> nKeepScrollBarsVisible;
- if (pBlockFlags[1] & 0x20)
- *pS >> fUnknown1; // another unknown 32 bit ( or is 8 or 16 bit with padding ? )
-
- if (pBlockFlags[1] & 0x80)
- {
- ReadAlign(pS, pS->Tell() - nStart, 2);
- *pS >> nIcon;
- DBG_ASSERT(nIcon == 0xFFFF, "Unexpected nIcon");
- }
-
- bool bCaption = false;
-
- if (pBlockFlags[2] & 0x01)
- *pS >> nCycle;
- if (pBlockFlags[2] & 0x02)
- *pS >> nSpecialEffect;
-
- if (pBlockFlags[2] & 0x04)
- {
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> nBorderColor;
- }
-
- if (pBlockFlags[2] & 0x08)
- {
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> nCaptionLen;
- bCaption = true;
- }
-
- if (pBlockFlags[2] & 0x10)
- {
- ReadAlign(pS, pS->Tell() - nStart, 2);
- sal_uInt16 nNoIdea;
- *pS >> nNoIdea;
- DBG_ASSERT(nNoIdea == 0xFFFF, "Expected 0xFFFF, (related to font ?)");
- }
-
- if (pBlockFlags[2] & 0x20)
- {
- ReadAlign(pS, pS->Tell() - nStart, 2);
- *pS >> nPicture;
- DBG_ASSERT(nPicture == 0xFFFF, "Unexpected nIcon");
- }
-
- if (pBlockFlags[2] & 0x80)
- *pS >> nPictureAlignment;
-
- if (pBlockFlags[3] & 0x01)
- bPictureTiling = true;
-
- if (pBlockFlags[3] & 0x02)
- *pS >> nPictureSizeMode;
-
- if (pBlockFlags[3] & 0x04)
- {
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> fUnknown8;
- }
-
- if (pBlockFlags[3] & 0x08)
- {
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> fUnknown9;
- }
-
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> nWidth;
- *pS >> nHeight;
- *pS >> nScrollWidth;
- *pS >> nScrollHeight;
-
- if (pBlockFlags[1] & 0x10)
- {
- *pS >> nScrollLeft;
- *pS >> nScrollTop;
- }
-
- if ( bCaption )
- {
- lclReadCharArray( *pS, pCaption, nCaptionLen, pS->Tell() - nStart);
- }
-
- OUString tempCaption = lclCreateOUString( pCaption, nCaptionLen );
-
- if (nIcon)
- {
- pS->Read(pIconHeader,20);
- *pS >> nIconLen;
- pIcon = new sal_uInt8[nIconLen];
- 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..
- pS->SeekRel(0x1a);
- sal_uInt8 nFontLen;
- *pS >> nFontLen;
- pS->SeekRel(nFontLen);
- }
-
- return OCX_ContainerControl::Read( pS );
+ return OCX_ParentControl::Read( pS );
}
sal_Bool OCX_Frame::Import(com::sun::star::uno::Reference<
@@ -4349,195 +3997,26 @@ sal_Bool OCX_Frame::Import(com::sun::star::uno::Reference<
rPropSet->setPropertyValue( WW8_ASCII2STR("Label"), aTmp);
}
+ aTmp <<= ImportColor(mnBackColor);
+ rPropSet->setPropertyValue( WW8_ASCII2STR("BackgroundColor"), aTmp);
+
// Calls import on contained controls
- OCX_ContainerControl::Import( rPropSet );
+ OCX_ParentControl::Import( rPropSet );
return sal_True;
}
+
OCX_UserForm::OCX_UserForm( SotStorageRef& parent,
const OUString& storageName,
const OUString& sN,
const ::uno::Reference< container::XNameContainer > &rDialog,
const ::uno::Reference< lang::XMultiServiceFactory >& rMsf):
- OCX_ContainerControl(parent, storageName, sN, rDialog),
- nChildrenA(0), fEnabled(1), fLocked(0),
- fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0), nVertPos(1),
- nHorzPos(7), nMousePointer(0), nBorderColor(0x80000012), nChildrenB(0),
- 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)
- {
- mnForeColor = 0x80000012;
- mnBackColor = 0x8000000F;
- uno::Reference< beans::XPropertySet> xProps( rMsf, uno::UNO_QUERY);
- if ( xProps.is() )
- {
- xProps->getPropertyValue(C2S("DefaultContext")) >>= mxCtx;
- }
- aFontData.SetHasAlign(TRUE);
- }
-sal_Bool OCX_UserForm::Read(SvStorageStream *pS)
-{
- long nStart = pS->Tell();
- *pS >> nIdentifier;
- DBG_ASSERT(0x400==nIdentifier,
- "A control that has a different identifier");
- *pS >> nFixedAreaLen;
- pS->Read(pBlockFlags,4);
-
- if (pBlockFlags[0] & 0x01)
+ OCX_ParentControl(parent, storageName, sN, rDialog )
{
- DBG_ASSERT(!this, "ARSE");
- }
- if (pBlockFlags[0] & 0x02)
- *pS >> mnBackColor;
- if (pBlockFlags[0] & 0x04)
- *pS >> mnForeColor;
- if (pBlockFlags[0] & 0x08)
- *pS >> nChildrenA;
- if (pBlockFlags[0] & 0x40)
- {
- sal_uInt8 nTemp;
- *pS >> nTemp;
- fEnabled = (nTemp&0x04)>>2;
- fBackStyle = (nTemp&0x08)>>3;
- *pS >> nTemp;
- *pS >> nTemp;
- fWordWrap = (nTemp&0x80)>>7;
- *pS >> nTemp;
- fAutoSize = (nTemp&0x10)>>4;
- }
- if (pBlockFlags[0] & 0x80)
- {
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> nBorderStyle;
- }
-#if 0
- sal_uInt16 nFixedOrAlign;
- *pS >> nFixedOrAlign;
-#endif
- if (pBlockFlags[1] & 0x01)
- *pS >> nMousePointer;
- if (pBlockFlags[1] & 0x02)
- *pS >> nKeepScrollBarsVisible;
- if (pBlockFlags[1] & 0x20)
+ uno::Reference< beans::XPropertySet> xProps( rMsf, uno::UNO_QUERY);
+ if ( xProps.is() )
{
- sal_uInt32 nUnknown32;
- *pS >> nUnknown32;
+ xProps->getPropertyValue(C2S("DefaultContext")) >>= mxCtx;
}
- if (pBlockFlags[1] & 0x80)
- {
- ReadAlign(pS, pS->Tell() - nStart, 2);
- *pS >> nIcon;
- DBG_ASSERT(nIcon == 0xFFFF, "Unexpected nIcon");
- }
- if (pBlockFlags[2] & 0x01)
- *pS >> nCycle;
- if (pBlockFlags[2] & 0x02)
- *pS >> nSpecialEffect;
-
- if (pBlockFlags[2] & 0x04)
- {
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> nBorderColor;
- }
-
- if (pBlockFlags[2] & 0x10)
- {
- ReadAlign(pS, pS->Tell() - nStart, 2);
- sal_uInt16 nNoIdea;
- *pS >> nNoIdea;
- DBG_ASSERT(nNoIdea == 0xFFFF, "Expected 0xFFFF, (related to font ?)");
- }
-
- if (pBlockFlags[2] & 0x20)
- {
- ReadAlign(pS, pS->Tell() - nStart, 2);
- *pS >> nPicture;
- DBG_ASSERT(nPicture == 0xFFFF, "Unexpected nIcon");
- }
-
- if (pBlockFlags[2] & 0x80)
- *pS >> nPictureAlignment;
-
- if (pBlockFlags[3] & 0x01)
- bPictureTiling = true;
-
- if (pBlockFlags[3] & 0x02)
- *pS >> nPictureSizeMode;
-
- if (pBlockFlags[3] & 0x04)
- {
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> nChildrenB;
- }
-
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> nDrawBuffer;
-
- ReadAlign(pS, pS->Tell() - nStart, 4);
- *pS >> nWidth;
- *pS >> nHeight;
- *pS >> nScrollWidth;
- *pS >> nScrollHeight;
-
- if (pBlockFlags[1] & 0x10)
- {
- *pS >> nScrollLeft;
- *pS >> nScrollTop;
- }
-
- if (nIcon)
- {
- pS->Read(pIconHeader,20);
- *pS >> nIconLen;
- pIcon = new sal_uInt8[nIconLen];
- pS->Read(pIcon,nIconLen);
- }
-
- ReadAlign( pS, pS->Tell() - nStart, 4);
- if (pBlockFlags[2] & 0x10)
- {
- //Font Stuff..
- pS->SeekRel(0x1a);
- sal_uInt8 nFontLen;
- *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;
- // seems to be no. of trailing records,
- // before container record starts proper
- // ( unknown what these trailing records are for)
- if ( numTrailingRecs )
- {
- for ( sal_Int16 i = 0 ; numTrailingRecs ; --numTrailingRecs, ++i )
- {
- sal_uInt16 nTypeID = 0;
- if ( lcl_handleActiveXControl( pS, nTypeID ) )
- {
- if ( nTypeID & 0x8000 ) // valid ActiveXID
- mActiveXIDMap[ ( i | 0x8000 ) ] = nTypeID;
- }
- }
- }
- return OCX_ContainerControl::Read( pS );
}
sal_Bool OCX_UserForm::Import(
@@ -4563,9 +4042,15 @@ sal_Bool OCX_UserForm::Import(
aTmp <<= sal_Int32( aAppFontSize.Height ); //100th mm
xDialogPropSet->setPropertyValue(WW8_ASCII2STR("Height"), aTmp);
+ if ( sImageUrl.getLength() )
+ {
+ aTmp <<= sImageUrl;
+ xDialogPropSet->setPropertyValue( WW8_ASCII2STR("ImageURL"), aTmp);
+ }
uno::Reference<beans::XPropertySet> xPropSet( mxParent, uno::UNO_QUERY );
- OCX_ContainerControl::Import( xPropSet );
+ OCX_ParentControl::Import( xPropSet );
+ uno::Reference< frame::XModel > xModel( pDocSh ? pDocSh->GetModel() : NULL );
uno::Reference<io::XInputStreamProvider> xSource =
xmlscript::exportDialogModel(mxParent, mxCtx, pDocSh->GetModel() );
@@ -5133,6 +4618,11 @@ sal_Bool OCX_CheckBox::Import(com::sun::star::uno::Reference<
rPropSet->setPropertyValue( WW8_ASCII2STR("VerticalAlign"), aTmp );
aFontData.Import(rPropSet);
+ if ( sImageUrl.getLength() )
+ {
+ aTmp <<= sImageUrl;
+ rPropSet->setPropertyValue( WW8_ASCII2STR("ImageURL"), aTmp);
+ }
return(sal_True);
}
@@ -5592,38 +5082,248 @@ sal_Bool HTML_TextBox::ReadFontData(SotStorageStream * /*pS*/)
return sal_True;
}
+sal_Bool HTML_TextBox::ReadFontData(SotStorageStream *pS)
+{
+ return sal_True;
+}
+
// Doesn't really read anything but just skips the
// record.
sal_Bool OCX_TabStrip::Read(SotStorageStream *pS)
{
- const long skipLen = 0x18;
+ long nStart = pS->Tell();
*pS >> nIdentifier;
DBG_ASSERT(nStandardId==nIdentifier,
"A control that has a different identifier");
*pS >> nFixedAreaLen;
pS->Read(pBlockFlags, sizeof(pBlockFlags));
- pS->SeekRel(skipLen);
- *pS >> nNumTabs;
- // skip to end of control
- pS->SeekRel(nFixedAreaLen - sizeof(pBlockFlags) - sizeof(nNumTabs) - skipLen );
- return sal_True;
-}
-sal_Bool OCX_TabStrip::ReadFontData(SotStorageStream *pS)
-{
- // Seems like there is a real font record followed by
- // a number of blank records ( e.g. nFixedAreaLen = 0 )
- // The number of trailing blank records is equal to the number of tabs
- OCX_Control::ReadFontData(pS);
- for ( sal_uInt16 index = 0; index < nNumTabs; index++ )
+ bool bSize = false;
+ bool bMultiRow = false;
+ bool bTooltips = true;
+ bool hasEmbeddedImage = false;
+ sal_Int32 nameSize = 0;
+ sal_Int32 tipStringSize = 0;
+ sal_Int32 nAcceleratorSize = 0;
+ sal_Int32 nItemSize = 0;
+ sal_Int32 nTagSize = 0;
+ if ( pBlockFlags[ 0 ] & 0x01 )
+ {
+ //List index
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_Int32 nOptional32 = 0; //
+ *pS >> nOptional32;
+ }
+ if (pBlockFlags[0] & 0x02)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> mnBackColor;
+ }
+ if (pBlockFlags[0] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> mnForeColor;
+ }
+ if (pBlockFlags[0] & 0x10)
+ bSize = true;
+ if (pBlockFlags[0] & 0x20)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nItemSize;
+ }
+ if (pBlockFlags[0] & 0x40)
+ {
+ sal_Int8 nOptional8 = 0; // mouse pointer
+ *pS >> nOptional8;
+ }
+ if (pBlockFlags[1] & 0x01)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_Int32 nOptional32 = 0; // taborientation
+ *pS >> nOptional32;
+ }
+ if (pBlockFlags[1] & 0x02)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_Int32 nOptional32 = 0; // tabstyle
+ *pS >> nOptional32;
+ if ( nOptional32 == 2 )
+ bHasTabs =false;
+ }
+ if (pBlockFlags[1] & 0x04)
+ bMultiRow = true;
+ if (pBlockFlags[1] & 0x08)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_Int32 nOptional32 = 0; // tabfixedwidth
+ *pS >> nOptional32;
+ }
+ if (pBlockFlags[1] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_Int32 nOptional32 = 0; // tabfixedheight
+ *pS >> nOptional32;
+ }
+ if (pBlockFlags[1] & 0x20)
+ bTooltips = false;
+
+ if (pBlockFlags[1] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> tipStringSize;
+ }
+
+ if (pBlockFlags[2] & 0x02)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nameSize;
+ }
+
+ if (pBlockFlags[2] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_Int32 nOptional32 = 0; // variouspropertybits
+ *pS >> nOptional32;
+ }
+
+ if (pBlockFlags[2] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_Int32 nOptional32 = 0; // tabsallocated
+ *pS >> nOptional32;
+ }
+
+ if (pBlockFlags[2] & 0x20)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nTagSize;
+ }
+
+ if (pBlockFlags[2] & 0x40)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nNumTabs;
+ }
+
+ if (pBlockFlags[2] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nAcceleratorSize;
+ }
+
+ if (pBlockFlags[3] & 0x01)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ sal_Int16 nOptional16 = 0; // Mouse Icon
+ *pS >> nOptional16;
+ hasEmbeddedImage = true;
+ }
+
+ // Extra block
+ if ( bSize )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nWidth;
+ *pS >> nHeight;
+ }
+ if ( nItemSize )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ // read the caption for each tab
+ readArrayString( pS, msItems, nItemSize, nStart );
+ std::vector< rtl::OUString >::iterator it = msItems.begin();
+ std::vector< rtl::OUString >::iterator it_end = msItems.end();
+ for ( sal_Int32 i=0; it != it_end; ++i, ++it )
+ OSL_TRACE(" Caption [ %d ] is %s", i, rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ if ( tipStringSize )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ // read the tip for each tab
+ std::vector< rtl::OUString > sTips;
+ readArrayString( pS, sTips, tipStringSize, nStart );
+ std::vector< rtl::OUString >::iterator it = sTips.begin();
+ std::vector< rtl::OUString >::iterator it_end = sTips.end();
+ for ( sal_Int32 i=0; it != it_end; ++i, ++it )
+ OSL_TRACE(" Tip [ %d ] is %s", i, rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ if ( nameSize )
{
- OCX_Control::Read(pS); // read trailing records
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ // read the name for each tab
+ std::vector< rtl::OUString > sNames;
+ readArrayString( pS, sNames, nameSize, nStart );
+ std::vector< rtl::OUString >::iterator it = sNames.begin();
+ std::vector< rtl::OUString >::iterator it_end = sNames.end();
+ for ( sal_Int32 i=0; it != it_end; ++i, ++it )
+ OSL_TRACE(" Name [ %d ] is %s", i, rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ if ( nTagSize )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ // read the name for each tab
+ std::vector< rtl::OUString > sTags;
+ readArrayString( pS, sTags, nTagSize, nStart );
+ std::vector< rtl::OUString >::iterator it = sTags.begin();
+ std::vector< rtl::OUString >::iterator it_end = sTags.end();
+ for ( sal_Int32 i=0; it != it_end; ++i, ++it )
+ OSL_TRACE(" Tag [ %d ] is %s", i, rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ if ( nAcceleratorSize )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ // read the name for each tab
+ std::vector< rtl::OUString > sAccelerators;
+ readArrayString( pS, sAccelerators, nAcceleratorSize, nStart );
+ std::vector< rtl::OUString >::iterator it = sAccelerators.begin();
+ std::vector< rtl::OUString >::iterator it_end = sAccelerators.end();
+ for ( sal_Int32 i=0; it != it_end; ++i, ++it )
+ OSL_TRACE(" Accelerator [ %d ] is %s", i, rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ // Stream data
+ if ( hasEmbeddedImage )
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen(0);
+ 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 );
+ }
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ OCX_Control::ReadFontData(pS); // read textprops
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ for ( sal_Int32 i = 0; i < nNumTabs; ++i )
+ {
+ sal_uInt32 TabStripTabFlags(0);
+ *pS >> TabStripTabFlags;
}
return sal_True;
}
+sal_Bool OCX_TabStrip::ReadFontData(SotStorageStream* /* pS */)
+{
+ // OCX_TabStrip::Read includes the text props
+ return true;
+}
+
sal_Bool OCX_Image::Read(SotStorageStream *pS)
{
ULONG nStart = pS->Tell();
@@ -5707,12 +5407,10 @@ sal_Bool OCX_Image::Read(SotStorageStream *pS)
if ( hasEmbeddedImage )
{
- //image follows this block
- //len of image is 0x14 relative to end of this block
- pS->Seek( pS->Tell() + 0x14 );
-
- sal_uInt32 nImageLen = 0;
- *pS >> nImageLen;
+ sal_uInt8 pPictureHeader[20];
+ sal_uInt32 nPictureLen(0);
+ pS->Read(pPictureHeader,20);
+ *pS >> nPictureLen;
long imagePos = pS->Tell();
@@ -5723,7 +5421,7 @@ sal_Bool OCX_Image::Read(SotStorageStream *pS)
sImageUrl = sImageUrl + mxGrfObj->getUniqueID();
}
// make sure the stream position should be pointing after the image
- pS->Seek( imagePos + nImageLen );
+ pS->Seek( imagePos + nPictureLen );
}
return sal_True;
}
@@ -6400,6 +6098,375 @@ sal_Bool OCX_ProgressBar::Import(uno::Reference< beans::XPropertySet > &rPropSet
rPropSet->setPropertyValue( WW8_ASCII2STR("Enabled"), uno::makeAny( sal_False ) );
return sal_True;
}
+
// ============================================================================
+OCX_ParentControl::OCX_ParentControl( SotStorageRef& parent, const OUString& storageName, const OUString& sN, const ::uno::Reference< container::XNameContainer > &rParent, OCX_Control* pParent ) : OCX_Control(sN, pParent), mxParent(rParent), nNextAvailableID(0), nBooleanProperties(0), nGroupCnt(0), nZoom(0), fEnabled(1), fLocked(0), fBackStyle(1), fWordWrap(1), fAutoSize(0), nCaptionLen(0), nVertPos(1), nHorzPos(7), nBorderColor(0x80000012), nShapeCookie(0), nKeepScrollBarsVisible(3), nCycle(0), nBorderStyle(0), nMousePointer(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)
+{
+ mnForeColor = 0x80000012;
+ mnBackColor = 0x8000000F;
+ aFontData.SetHasAlign(TRUE);
+ mContainerStorage = parent->OpenSotStorage(storageName,
+ STREAM_READWRITE |
+ STREAM_NOCREATE |
+ STREAM_SHARE_DENYALL);
+ mContainerStream = mContainerStorage->OpenSotStream(
+ String(RTL_CONSTASCII_STRINGPARAM("f"),
+ RTL_TEXTENCODING_MS_1252),
+ STREAM_STD_READ | STREAM_NOCREATE);
+ mContainedControlsStream = mContainerStorage->OpenSotStream( String(RTL_CONSTASCII_STRINGPARAM("o"),
+ RTL_TEXTENCODING_MS_1252),
+ STREAM_STD_READ | STREAM_NOCREATE);
+}
+
+OCX_ParentControl::~OCX_ParentControl()
+{
+ CtrlIterator aEnd = mpControls.end();
+ for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
+ {
+ delete *aIter;
+ }
+}
+
+sal_Bool OCX_ParentControl::Import(uno::Reference<beans::XPropertySet>& rProps )
+{
+ // #FIXME we probably don't need this (fake) parent (mxParen) which is the dialog iirc
+ if ( !mxParent.is() )
+ {
+ return sal_False;
+ }
+ CtrlIterator aEnd = mpControls.end();
+// int count = 0;
+ for (CtrlIterator aIter = mpControls.begin(); aIter != aEnd; ++ aIter )
+ {
+ uno::Reference< container::XNameContainer > xNameContainer( rProps, uno::UNO_QUERY );
+ if ( !(*aIter)->Import( xNameContainer ) )
+ {
+ return sal_False;
+ }
+ }
+ return sal_True;
+}
+
+bool OCX_ParentControl::createFromContainerRecord( const ContainerRecord& record, OCX_Control*& pControl )
+{
+ pControl = NULL;
+ switch ( record.nTypeIdent)
+ {
+ case CMDBUTTON:
+ pControl = new OCX_CommandButton;
+ break;
+ case LABEL:
+ pControl = new OCX_UserFormLabel(this);
+ break;
+ case TEXTBOX:
+ pControl = new OCX_TextBox;
+ break;
+ case LISTBOX:
+ pControl = new OCX_ListBox;
+ break;
+ case COMBOBOX:
+ pControl = new OCX_ComboBox;
+ break;
+ case CHECKBOX:
+ pControl = new OCX_CheckBox;
+ break;
+ case OPTIONBUTTON:
+ pControl = new OCX_OptionButton;
+ break;
+ case TOGGLEBUTTON:
+ pControl = new OCX_ToggleButton;
+ break;
+ case IMAGE: //Image
+ {
+ pControl = new OCX_Image;
+ break;
+ }
+ case PAGE: // Page
+ {
+ pControl = new OCX_Page(mContainerStorage, record.nSubStorageId,
+ record.cName, mxParent, this);
+ break;
+ }
+ case MULTIPAGE: // MultiPage
+ {
+ OUString sMSStore = createSubStreamName( record.nSubStorageId );
+ pControl = new OCX_MultiPage( mContainerStorage, sMSStore,
+ record.cName, mxParent, this);
+ break;
+ }
+ case FRAME: //Frame
+ {
+ OUString sFrameStore = createSubStreamName( record.nSubStorageId );
+ pControl = new OCX_Frame(mContainerStorage, sFrameStore,
+ record.cName, mxParent, this);
+
+ break;
+ }
+ case SPINBUTTON: //SpinButton
+ {
+ pControl = new OCX_SpinButton;
+ break;
+ }
+ case TABSTRIP: //TabStrip
+ {
+ pControl = new OCX_TabStrip;
+ break;
+ }
+ case SCROLLBAR: //ScrollBar
+ pControl = new OCX_ScrollBar;
+ break;
+ case PROGRESSBAR: //ProgressBar Active X control
+ pControl = new OCX_ProgressBar;
+ break;
+ default:
+ OSL_TRACE( "**** Unknown control 0x%x", record.nTypeIdent );
+ DBG_ERROR( "Unknown control");
+ return false;
+ }
+ pControl->sName = record.cName;
+
+ pControl->msToolTip = record.controlTip;
+ pControl->mnTop = record.nTop;
+ pControl->mnLeft = record.nLeft;
+ // MS tabIndex, pretty useless in OpenOffice land
+ // as tab indexes in MS are relative to parent container.
+ // However we need this value in order to set
+ // OpenOffice tab indices in a sensible way to
+ // reflect the ms tabbing from orig MS UserForm, see below
+ pControl->mnTabPos = record.nTabPos;
+ pControl->SetInDialog(true);
+ pControl->mbVisible = record.bVisible;
+
+ return true;
+}
+
+void OCX_ParentControl::ProcessControl(OCX_Control* pControl,SvStorageStream* /* pS */, ContainerRecord& rec )
+{
+ SotStorageStreamRef oStream = mContainedControlsStream;
+
+ // can insert into OO Dialog (e.g is this a supported dialog control)??
+ if ( rec.nTypeIdent == TABSTRIP )
+ {
+ // skip the record in the stream, discard the control
+ oStream->SeekRel( rec.nSubStreamLen );
+ delete pControl;
+ }
+ else
+ {
+ // 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 )
+ {
+ OCX_ParentControl* pContainer =
+ static_cast< OCX_ParentControl* >( pControl );
+ oStream = pContainer->getContainerStream();
+ }
+ // #117490# DR: container records provide size of substream, use it here...
+
+ // remember initial position to set correct stream position
+ ULONG nStrmPos = oStream->Tell();
+ // import control, may return with invalid stream position
+ pControl->FullRead(oStream);
+ // set stream to position behind substream of this control
+ oStream->Seek( nStrmPos + rec.nSubStreamLen );
+ }
+}
+
+sal_Bool OCX_ParentControl::Read(SvStorageStream *pS)
+{
+ long nStart = pS->Tell();
+
+ *pS >> nIdentifier;
+ DBG_ASSERT(0x400==nIdentifier,
+ "A control that has a different identifier");
+ *pS >> nFixedAreaLen;
+ pS->Read(pBlockFlags,4);
+
+ bool bExtraSize = false;
+ bool bLogicalSize = false;
+ bool bScrollPosition = false;
+ bool bFont = false;
+ if (pBlockFlags[0] & 0x01)
+ {
+ DBG_ASSERT(!this, "ARSE");
+ }
+ if (pBlockFlags[0] & 0x02)
+ *pS >> mnBackColor;
+ if (pBlockFlags[0] & 0x04)
+ *pS >> mnForeColor;
+ if (pBlockFlags[0] & 0x08)
+ *pS >> nNextAvailableID;
+ if (pBlockFlags[0] & 0x40)
+ *pS >> nBooleanProperties;
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ if (pBlockFlags[0] & 0x80)
+ {
+ *pS >> nBorderStyle;
+ }
+ if (pBlockFlags[1] & 0x01)
+ *pS >> nMousePointer;
+ if (pBlockFlags[1] & 0x02)
+ *pS >> nKeepScrollBarsVisible;
+ if (pBlockFlags[1] & 0x04)
+ bExtraSize = true;
+ if (pBlockFlags[1] & 0x08)
+ bLogicalSize = true;
+ if (pBlockFlags[1] & 0x10)
+ bScrollPosition = true;
+ if (pBlockFlags[1] & 0x20)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nGroupCnt;
+ }
+
+ if (pBlockFlags[1] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nIcon;
+ DBG_ASSERT(nIcon == 0xFFFF, "Unexpected nIcon");
+ }
+ if (pBlockFlags[2] & 0x01)
+ *pS >> nCycle;
+ if (pBlockFlags[2] & 0x02)
+ *pS >> nSpecialEffect;
+ if (pBlockFlags[2] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nBorderColor;
+ }
+ if (pBlockFlags[2] & 0x08)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nCaptionLen;
+ }
+
+ if (pBlockFlags[2] & 0x10)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ sal_uInt16 nNoIdea;
+ *pS >> nNoIdea;
+ DBG_ASSERT(nNoIdea == 0xFFFF, "Expected 0xFFFF, (related to font ?)");
+ bFont = true;
+ }
+ if (pBlockFlags[2] & 0x20)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 2);
+ *pS >> nPicture;
+ DBG_ASSERT(nPicture == 0xFFFF, "Unexpected nIcon");
+ }
+
+ if (pBlockFlags[2] & 0x40)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nZoom;
+ }
+ if (pBlockFlags[2] & 0x80)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nPictureAlignment;
+ }
+
+ if (pBlockFlags[3] & 0x01)
+ bPictureTiling = true;
+
+ if (pBlockFlags[3] & 0x02)
+ *pS >> nPictureSizeMode;
+
+ if (pBlockFlags[3] & 0x04)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nShapeCookie;
+ }
+ if (pBlockFlags[3] & 0x08)
+ {
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ *pS >> nDrawBuffer;
+ }
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+ // Extra
+ if ( bExtraSize )
+ {
+ *pS >> nWidth;
+ *pS >> nHeight;
+ }
+ if ( bLogicalSize )
+ {
+ *pS >> nScrollWidth;
+ *pS >> nScrollHeight;
+ }
+ if ( bScrollPosition )
+ {
+ *pS >> nScrollLeft;
+ *pS >> nScrollTop;
+ }
+ if ( nCaptionLen )
+ {
+ sal_uInt32 nCaptionSize = lclGetBufferSize( nCaptionLen );
+ if ( nCaptionSize )
+ {
+ pCaption = new sal_Char[ nCaptionSize ];
+ pS->Read( pCaption, nCaptionSize );
+ }
+ }
+
+ ReadAlign(pS, pS->Tell() - nStart, 4);
+
+ // StreamData
+ if (nIcon)
+ {
+ pS->Read(pIconHeader,20);
+ *pS >> nIconLen;
+ pIcon = new sal_uInt8[nIconLen];
+ pS->Read(pIcon,nIconLen);
+ }
+ if ( bFont )
+ {
+ //Font Stuff..
+ pS->SeekRel(0x1a);
+ sal_uInt8 nFontLen;
+ *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 );
+ }
+ // FormSiteData
+ std::vector< ClassTable > siteClassInfo;
+ if ( ( nBooleanProperties & 0x00008000 ) == 0x0)
+ {
+ sal_Int16 numTrailingRecs = 0;
+ *pS >> numTrailingRecs;
+ if ( numTrailingRecs )
+ {
+ for ( ; numTrailingRecs ; --numTrailingRecs )
+ {
+ ClassTable cacheClass;
+ cacheClass.Read( pS );
+ siteClassInfo.push_back( cacheClass );
+ }
+ }
+ }
+ // Sites
+ ContainerRecReader reader;
+ reader.Read( this, pS, siteClassInfo );
+
+ return true;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/msfilter/msvbahelper.cxx b/filter/source/msfilter/msvbahelper.cxx
index 5baf69bf11a5..95b7a7d6ad93 100644
--- a/filter/source/msfilter/msvbahelper.cxx
+++ b/filter/source/msfilter/msvbahelper.cxx
@@ -37,6 +37,7 @@
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentInfoSupplier.hpp>
+#include <com/sun/star/script/vba/XVBACompatibility.hpp>
#include <tools/urlobj.hxx>
#include <osl/file.hxx>
#include <unotools/pathoptions.hxx>
@@ -287,15 +288,15 @@ VBAMacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUStrin
{
// Ok, if we have no Container specified then we need to search them in order, this document, template this document created from, global templates,
// get the name of Project/Library for 'this' document
- rtl::OUString sThisProject;
- BasicManager* pBasicMgr = pShell-> GetBasicManager();
- if ( pBasicMgr )
+ rtl::OUString sThisProject = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") );
+ try
{
- if ( pBasicMgr->GetName().Len() )
- sThisProject = pBasicMgr->GetName();
- else // cater for the case where VBA is not enabled
- sThisProject = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") );
+ uno::Reference< beans::XPropertySet > xProps( pShell->GetModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< script::vba::XVBACompatibility > xVBAMode( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("BasicLibraries") ) ), uno::UNO_QUERY_THROW );
+ sThisProject = xVBAMode->getProjectName();
}
+ catch( uno::Exception& /*e*/) {}
+
sSearchList.push_back( sThisProject ); // First Lib to search
if ( xPrjNameCache.is() )
{
diff --git a/oox/inc/oox/helper/containerhelper.hxx b/oox/inc/oox/helper/containerhelper.hxx
index 55c609924720..9a0a0774c43b 100644
--- a/oox/inc/oox/helper/containerhelper.hxx
+++ b/oox/inc/oox/helper/containerhelper.hxx
@@ -125,6 +125,13 @@ public:
forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) );
}
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3, typename ParamType4 >
+ inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3, ParamType4 aParam4 ) const
+ {
+ forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3, aParam4 ) );
+ }
/** Calls the passed functor for every contained object. Passes the index as
first argument and the object reference as second argument to rFunctor. */
template< typename FunctorType >
@@ -282,6 +289,13 @@ public:
{
forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3 ) );
}
+ /** Calls the passed member function of ObjType on every contained object,
+ automatically skips all elements that are empty references. */
+ template< typename FuncType, typename ParamType1, typename ParamType2, typename ParamType3, typename ParamType4 >
+ inline void forEachMem( FuncType pFunc, ParamType1 aParam1, ParamType2 aParam2, ParamType3 aParam3, ParamType4 aParam4 ) const
+ {
+ forEach( ::boost::bind( pFunc, _1, aParam1, aParam2, aParam3, aParam4 ) );
+ }
/** Calls the passed functor for every contained object. Passes the key as
first argument and the object reference as second argument to rFunctor. */
template< typename FunctorType >
diff --git a/oox/inc/oox/ole/axcontrol.hxx b/oox/inc/oox/ole/axcontrol.hxx
index 4152857cad73..eccd5865cfa9 100644
--- a/oox/inc/oox/ole/axcontrol.hxx
+++ b/oox/inc/oox/ole/axcontrol.hxx
@@ -31,6 +31,7 @@
#include <boost/shared_ptr.hpp>
#include "oox/helper/binarystreambase.hxx"
+#include "oox/helper/propertyset.hxx"
#include "oox/ole/axbinaryreader.hxx"
#include "oox/ole/olehelper.hxx"
@@ -38,6 +39,7 @@ namespace com { namespace sun { namespace star {
namespace awt { class XControlModel; }
namespace container { class XIndexContainer; }
namespace drawing { class XDrawPage; }
+ namespace frame { class XModel; }
namespace form { class XFormsSupplier; }
namespace lang { class XMultiServiceFactory; }
} } }
@@ -148,6 +150,7 @@ class ControlConverter
{
public:
explicit ControlConverter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
const GraphicHelper& rGraphicHelper,
bool bDefaultColorBgr = true );
virtual ~ControlConverter();
@@ -186,6 +189,14 @@ public:
sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nPosition,
sal_Int32 nSmallChange, sal_Int32 nLargeChange, bool bAwtModel ) const;
+ /** Binds the passed control model to the passed data sources. The
+ implementation will check which source types are supported. */
+ void bindToSources(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel,
+ const ::rtl::OUString& rCtrlSource,
+ const ::rtl::OUString& rRowSource,
+ sal_Int32 nRefSheet = 0 ) const;
+
// ActiveX (Forms 2.0) specific conversion --------------------------------
/** Converts the Forms 2.0 background formatting to UNO properties. */
@@ -239,7 +250,10 @@ public:
sal_Int32 nOrientation ) const;
private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxDocModel;
const GraphicHelper& mrGraphicHelper;
+ mutable PropertySet maAddressConverter;
+ mutable PropertySet maRangeConverter;
bool mbDefaultColorBgr;
};
@@ -805,7 +819,7 @@ class EmbeddedForm : public ControlConverter
{
public:
explicit EmbeddedForm(
- const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxModelFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& rxDrawPage,
const GraphicHelper& rGraphicHelper,
bool bDefaultColorBgr = true );
diff --git a/oox/inc/oox/ole/vbacontrol.hxx b/oox/inc/oox/ole/vbacontrol.hxx
index 8f419cd6290e..df25e746bc6d 100644
--- a/oox/inc/oox/ole/vbacontrol.hxx
+++ b/oox/inc/oox/ole/vbacontrol.hxx
@@ -84,12 +84,19 @@ public:
ApiControlType eCtrlType,
sal_Int32 nCtrlIndex ) const;
+ /** Binds the passed control model to the data sources. The implementation
+ will check which source types are supported. */
+ void bindToSources(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel,
+ const ControlConverter& rConv ) const;
+
protected:
::rtl::OUString maName; /// Name of the control.
::rtl::OUString maTag; /// User defined tag.
::rtl::OUString maToolTip; /// Tool tip for the control.
- ::rtl::OUString maLinkedCell; /// Linked cell for the control value in a spreadsheet.
- ::rtl::OUString maSourceRange; /// Source data for the control in a spreadsheet.
+ ::rtl::OUString maControlSource; /// Linked cell for the control value in a spreadsheet.
+ ::rtl::OUString maRowSource; /// Source data for the control in a spreadsheet.
+
AxPairData maPos; /// Position in parent container.
sal_Int32 mnId; /// Control identifier.
sal_Int32 mnHelpContextId; /// Help context identifier.
@@ -161,13 +168,7 @@ private:
/** Imports the site models of all embedded controls from the 'f' stream. */
bool importEmbeddedSiteModels( BinaryInputStream& rInStrm );
/* Final processing of all embedded controls after import. */
- void finalizeEmbeddedControls();
-
- /** Moves the control relative to its current position by the passed distance. */
- void moveRelative( const AxPairData& rDistance );
- /** Moves all embedded controls from their relative position in this
- control to an absolute position in the parent of this control. */
- void moveEmbeddedToAbsoluteParent();
+ void finalizeEmbeddedControls( StorageBase& rStrg );
/** Functor for comparing controls by their tab index. */
static bool compareByTabIndex( const VbaFormControlRef& rxLeft, const VbaFormControlRef& rxRight );
@@ -183,11 +184,12 @@ private:
// ============================================================================
-class VbaUserForm : public VbaFormControl, public ControlConverter
+class VbaUserForm : public VbaFormControl
{
public:
explicit VbaUserForm(
const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxGlobalFactory,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
const GraphicHelper& rGraphicHelper,
bool bDefaultColorBgr = true );
@@ -202,6 +204,8 @@ public:
private:
::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxGlobalFactory;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxDocModel;
+ ControlConverter maConverter;
};
// ============================================================================
diff --git a/oox/inc/oox/ole/vbahelper.hxx b/oox/inc/oox/ole/vbahelper.hxx
index 8ab2159f5be1..1f67a7759aa6 100644
--- a/oox/inc/oox/ole/vbahelper.hxx
+++ b/oox/inc/oox/ole/vbahelper.hxx
@@ -55,6 +55,7 @@ const sal_uInt16 VBA_ID_MODULETYPEPROCEDURAL = 0x0021;
const sal_uInt16 VBA_ID_PROJECTCODEPAGE = 0x0003;
const sal_uInt16 VBA_ID_PROJECTEND = 0x0010;
const sal_uInt16 VBA_ID_PROJECTMODULES = 0x000F;
+const sal_uInt16 VBA_ID_PROJECTNAME = 0x0004;
const sal_uInt16 VBA_ID_PROJECTVERSION = 0x0009;
// ============================================================================
diff --git a/oox/inc/oox/ole/vbamodule.hxx b/oox/inc/oox/ole/vbamodule.hxx
index 521a5bf5907c..52d04c0e5d45 100644
--- a/oox/inc/oox/ole/vbamodule.hxx
+++ b/oox/inc/oox/ole/vbamodule.hxx
@@ -69,10 +69,31 @@ public:
/** Imports all records for this module until the MODULEEND record. */
void importDirRecords( BinaryInputStream& rDirStrm );
- /** Imports the Basic source code into the passed Basic library. */
- void importSourceCode(
+
+ /** Imports the VBA source code into the passed Basic library. */
+ void createAndImportModule(
StorageBase& rVbaStrg,
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxOleNameOverrides ) const;
+ /** Creates an empty Basic module in the passed Basic library. */
+ void createEmptyModule(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;
+
+private:
+ /** Reads and returns the VBA source code from the passed storage. */
+ ::rtl::OUString readSourceCode(
+ StorageBase& rVbaStrg,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxOleNameOverrides ) const;
+
+ void extractOleOverrideFromAttr( const rtl::OUString& rAttribute,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxOleNameOverrides ) const;
+
+ /** Creates a new Basic module and inserts it into the passed Basic library. */
+ void createModule(
+ const ::rtl::OUString& rVBASourceCode,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;
private:
diff --git a/oox/inc/oox/ole/vbaproject.hxx b/oox/inc/oox/ole/vbaproject.hxx
index b5bb1dc766fd..fc10e1de3e62 100644
--- a/oox/inc/oox/ole/vbaproject.hxx
+++ b/oox/inc/oox/ole/vbaproject.hxx
@@ -29,9 +29,9 @@
#ifndef OOX_OLE_VBAPROJECT_HXX
#define OOX_OLE_VBAPROJECT_HXX
-#include "oox/helper/storagebase.hxx"
+#include <map>
#include <com/sun/star/uno/XInterface.hpp>
-#include "oox/dllapi.h"
+#include "oox/helper/storagebase.hxx"
namespace com { namespace sun { namespace star {
namespace container { class XNameContainer; }
@@ -48,7 +48,7 @@ namespace ole {
// ============================================================================
-class OOX_DLLPUBLIC VbaFilterConfig
+class VbaFilterConfig
{
public:
explicit VbaFilterConfig(
@@ -70,7 +70,7 @@ private:
// ============================================================================
-class OOX_DLLPUBLIC VbaProject : public VbaFilterConfig
+class VbaProject : public VbaFilterConfig
{
public:
explicit VbaProject(
@@ -98,6 +98,8 @@ public:
/** Returns true, if the document contains the specified dialog. */
bool hasDialog( const ::rtl::OUString& rDialogName ) const;
+ void setOleOverridesSink( ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxOleOverridesSink ){ mxOleOverridesSink = rxOleOverridesSink; }
+
private:
VbaProject( const VbaProject& );
VbaProject& operator=( const VbaProject& );
@@ -115,11 +117,26 @@ private:
::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
createDialogLibrary();
/** Imports the VBA code modules and forms. */
- void importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr );
+ void importVba(
+ StorageBase& rVbaPrjStrg,
+ const GraphicHelper& rGraphicHelper,
+ bool bDefaultColorBgr );
+
/** Copies the entire VBA project storage to the passed document model. */
void copyStorage( StorageBase& rVbaPrjStrg );
+
+protected:
+ /** Registers a dummy module that will be created when the VBA project is
+ imported. */
+ void addDummyModule( const ::rtl::OUString& rName, sal_Int32 nType );
+
+ /** Called when the import process of the VBA code modules starts. */
+ virtual void prepareModuleImport();
+
private:
+ typedef ::std::map< ::rtl::OUString, sal_Int32 > DummyModuleMap;
+
::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
mxGlobalFactory; /// Global service factory.
::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
@@ -128,7 +145,10 @@ private:
mxBasicLib; /// The Basic library of the document used for import.
::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
mxDialogLib; /// The dialog library of the document used for import.
- const ::rtl::OUString maLibName; /// Name for Basic and dialog library used for import.
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
+ mxOleOverridesSink;
+ DummyModuleMap maDummyModules; /// Additional empty modules created on import.
+ ::rtl::OUString maPrjName; /// Name of the VBA project.
};
// ============================================================================
diff --git a/oox/inc/oox/xls/drawingfragment.hxx b/oox/inc/oox/xls/drawingfragment.hxx
index 7a6de04adca5..71d60433e4c6 100644
--- a/oox/inc/oox/xls/drawingfragment.hxx
+++ b/oox/inc/oox/xls/drawingfragment.hxx
@@ -32,6 +32,7 @@
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/awt/Size.hpp>
#include "oox/drawingml/shape.hxx"
+#include "oox/ole/axcontrol.hxx"
#include "oox/vml/vmldrawing.hxx"
#include "oox/vml/vmldrawingfragment.hxx"
#include "oox/xls/excelhandlers.hxx"
@@ -183,6 +184,10 @@ public:
virtual void notifyShapeInserted(
const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
const ::com::sun::star::awt::Rectangle& rShapeRect );
+
+private:
+ ::oox::ole::ControlConverter maControlConv;
+
};
// ============================================================================
diff --git a/oox/inc/oox/xls/excelfilter.hxx b/oox/inc/oox/xls/excelfilter.hxx
index 407533f80016..f3e4a571653c 100644
--- a/oox/inc/oox/xls/excelfilter.hxx
+++ b/oox/inc/oox/xls/excelfilter.hxx
@@ -31,6 +31,7 @@
#include "oox/core/xmlfilterbase.hxx"
#include "oox/core/binaryfilterbase.hxx"
+#include "oox/ole/vbaprojectfilter.hxx"
namespace oox {
namespace xls {
@@ -97,6 +98,20 @@ private:
// ============================================================================
+class ExcelVbaProjectFilter : public ExcelBiffFilter
+{
+public:
+ explicit ExcelVbaProjectFilter(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxGlobalFactory );
+
+ virtual bool importDocument() throw();
+
+private:
+ virtual ::rtl::OUString implGetImplementationName() const;
+};
+
+// ============================================================================
+
} // namespace xls
} // namespace oox
diff --git a/oox/prj/d.lst b/oox/prj/d.lst
index 70c7c1ea52ef..c92cf4dd8a90 100644
--- a/oox/prj/d.lst
+++ b/oox/prj/d.lst
@@ -26,6 +26,7 @@ mkdir: %_DEST%\inc%_EXT%\oox\xls
..\inc\oox\helper\binarystreambase.hxx %_DEST%\inc%_EXT%\oox\helper\binarystreambase.hxx
..\inc\oox\helper\helper.hxx %_DEST%\inc%_EXT%\oox\helper\helper.hxx
..\inc\oox\helper\containerhelper.hxx %_DEST%\inc%_EXT%\oox\helper\containerhelper.hxx
+..\inc\oox\helper\graphichelper.hxx %_DEST%\inc%_EXT%\oox\helper\graphichelper.hxx
..\inc\oox\helper\storagebase.hxx %_DEST%\inc%_EXT%\oox\helper\storagebase.hxx
..\inc\oox\helper\zipstorage.hxx %_DEST%\inc%_EXT%\oox\helper\zipstorage.hxx
..\inc\oox\core\filterbase.hxx %_DEST%\inc%_EXT%\oox\core\filterbase.hxx
diff --git a/oox/source/core/facreg.cxx b/oox/source/core/facreg.cxx
index 590cdd876e93..36dbe9f8ce95 100644
--- a/oox/source/core/facreg.cxx
+++ b/oox/source/core/facreg.cxx
@@ -61,6 +61,8 @@ namespace oox {
namespace xls { SERVICE( BiffDetector ); }
namespace xls { SERVICE( ExcelFilter ); }
namespace xls { SERVICE( ExcelBiffFilter ); }
+ namespace xls { SERVICE( ExcelVbaProjectFilter ); }
+ namespace ole { SERVICE( WordVbaProjectFilter ); }
namespace shape { SERVICE( ShapeContextHandler ); }
namespace shape { SERVICE( FastTokenHandlerService ); }
namespace docprop { SERVICE2( OOXMLDocPropImportImpl ); }
@@ -104,6 +106,8 @@ OOX_DLLPUBLIC sal_Bool SAL_CALL component_writeInfo( void * , void * pRegistryKe
WRITEINFO( ::oox::xls::BiffDetector );
WRITEINFO( ::oox::xls::ExcelFilter );
WRITEINFO( ::oox::xls::ExcelBiffFilter );
+ WRITEINFO( ::oox::xls::ExcelVbaProjectFilter );
+ WRITEINFO( ::oox::ole::WordVbaProjectFilter );
WRITEINFO( ::oox::shape::ShapeContextHandler );
WRITEINFO( ::oox::shape::FastTokenHandlerService );
WRITEINFO( ::oox::docprop::OOXMLDocPropImportImpl );
@@ -152,6 +156,8 @@ OOX_DLLPUBLIC void * SAL_CALL component_getFactory( const sal_Char * pImplName,
else SINGLEFACTORY( ::oox::xls::BiffDetector )
else SINGLEFACTORY( ::oox::xls::ExcelFilter )
else SINGLEFACTORY( ::oox::xls::ExcelBiffFilter )
+ else SINGLEFACTORY( ::oox::xls::ExcelVbaProjectFilter )
+ else SINGLEFACTORY( ::oox::ole::WordVbaProjectFilter )
else SINGLEFACTORY( ::oox::shape::ShapeContextHandler)
else SINGLEFACTORY( ::oox::shape::FastTokenHandlerService)
else SINGLEFACTORY2( ::oox::docprop::OOXMLDocPropImportImpl )
diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx
index 58f50cfab78d..bd484dc8d92b 100644
--- a/oox/source/ole/axcontrol.cxx
+++ b/oox/source/ole/axcontrol.cxx
@@ -27,7 +27,7 @@
************************************************************************/
#include "oox/ole/axcontrol.hxx"
-#include <rtl/tencinfo.h>
+
#include <com/sun/star/awt/FontSlant.hpp>
#include <com/sun/star/awt/FontStrikeout.hpp>
#include <com/sun/star/awt/FontUnderline.hpp>
@@ -40,42 +40,50 @@
#include <com/sun/star/awt/TextAlign.hpp>
#include <com/sun/star/awt/VisualEffect.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/form/XFormComponent.hpp>
#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
#include <com/sun/star/style/VerticalAlignment.hpp>
-#include "properties.hxx"
-#include "tokens.hxx"
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <rtl/tencinfo.h>
#include "oox/helper/attributelist.hxx"
#include "oox/helper/binaryinputstream.hxx"
#include "oox/helper/graphichelper.hxx"
#include "oox/helper/propertymap.hxx"
-#include "oox/helper/propertyset.hxx"
-
-using ::rtl::OUString;
-using ::com::sun::star::awt::Point;
-using ::com::sun::star::awt::Size;
-using ::com::sun::star::awt::XControlModel;
-using ::com::sun::star::container::XIndexContainer;
-using ::com::sun::star::container::XNameContainer;
-using ::com::sun::star::drawing::XDrawPage;
-using ::com::sun::star::form::XForm;
-using ::com::sun::star::form::XFormComponent;
-using ::com::sun::star::lang::XMultiServiceFactory;
-using ::com::sun::star::uno::Any;
-using ::com::sun::star::uno::Exception;
-using ::com::sun::star::uno::Reference;
-using ::com::sun::star::uno::UNO_QUERY;
-using ::com::sun::star::uno::UNO_QUERY_THROW;
-using ::com::sun::star::uno::UNO_SET_THROW;
+#include "properties.hxx"
+#include "tokens.hxx"
namespace oox {
namespace ole {
// ============================================================================
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::form;
+using namespace ::com::sun::star::form::binding;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+// ============================================================================
+
namespace {
const sal_uInt32 COMCTL_ID_SIZE = 0x12344321;
@@ -221,14 +229,70 @@ const sal_Int16 API_STATE_UNCHECKED = 0;
const sal_Int16 API_STATE_CHECKED = 1;
const sal_Int16 API_STATE_DONTKNOW = 2;
+// ----------------------------------------------------------------------------
+
+/** Tries to extract a range address from a defined name. */
+bool lclExtractRangeFromName( CellRangeAddress& orRangeAddr, const Reference< XModel >& rxDocModel, const OUString& rAddressString )
+{
+ try
+ {
+ PropertySet aPropSet( rxDocModel );
+ Reference< XNameAccess > xRangesNA( aPropSet.getAnyProperty( PROP_NamedRanges ), UNO_QUERY_THROW );
+ Reference< XCellRangeReferrer > xReferrer( xRangesNA->getByName( rAddressString ), UNO_QUERY_THROW );
+ Reference< XCellRangeAddressable > xAddressable( xReferrer->getReferredCells(), UNO_QUERY_THROW );
+ orRangeAddr = xAddressable->getRangeAddress();
+ return true;
+ }
+ catch( Exception& )
+ {
+ }
+ return false;
+}
+
+bool lclExtractAddressFromName( CellAddress& orAddress, const Reference< XModel >& rxDocModel, const OUString& rAddressString )
+{
+ CellRangeAddress aRangeAddr;
+ if( lclExtractRangeFromName( aRangeAddr, rxDocModel, rAddressString ) &&
+ (aRangeAddr.StartColumn == aRangeAddr.EndColumn) &&
+ (aRangeAddr.StartRow == aRangeAddr.EndRow) )
+ {
+ orAddress.Sheet = aRangeAddr.Sheet;
+ orAddress.Column = aRangeAddr.StartColumn;
+ orAddress.Row = aRangeAddr.StartRow;
+ return true;
+ }
+ return false;
+}
+
+void lclPrepareConverter( PropertySet& rConverter, const Reference< XModel >& rxDocModel,
+ const OUString& rAddressString, sal_Int32 nRefSheet, bool bRange )
+{
+ if( !rConverter.is() ) try
+ {
+ Reference< XMultiServiceFactory > xFactory( rxDocModel, UNO_QUERY_THROW );
+ OUString aServiceName = bRange ?
+ CREATE_OUSTRING( "com.sun.star.table.CellRangeAddressConversion" ) :
+ CREATE_OUSTRING( "com.sun.star.table.CellAddressConversion" );
+ rConverter.set( xFactory->createInstance( aServiceName ) );
+ }
+ catch( Exception& )
+ {
+ }
+ rConverter.setProperty( PROP_XLA1Representation, rAddressString );
+ rConverter.setProperty( PROP_ReferenceSheet, nRefSheet );
+}
+
} // namespace
// ============================================================================
-ControlConverter::ControlConverter( const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
+ControlConverter::ControlConverter( const Reference< XModel >& rxDocModel,
+ const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
+ mxDocModel( rxDocModel ),
mrGraphicHelper( rGraphicHelper ),
mbDefaultColorBgr( bDefaultColorBgr )
{
+ OSL_ENSURE( mxDocModel.is(), "ControlConverter::ControlConverter - missing document model" );
}
ControlConverter::~ControlConverter()
@@ -286,6 +350,74 @@ void ControlConverter::convertScrollBar( PropertyMap& rPropMap,
rPropMap.setProperty( bAwtModel ? PROP_ScrollValue : PROP_DefaultScrollValue, nPosition );
}
+void ControlConverter::bindToSources( const Reference< XControlModel >& rxCtrlModel,
+ const OUString& rCtrlSource, const OUString& rRowSource, sal_Int32 nRefSheet ) const
+{
+ // value binding
+ if( rCtrlSource.getLength() > 0 ) try
+ {
+ // first check if the XBindableValue interface is supported
+ Reference< XBindableValue > xBindable( rxCtrlModel, UNO_QUERY_THROW );
+
+ // convert address string to cell address struct
+ CellAddress aAddress;
+ if( !lclExtractAddressFromName( aAddress, mxDocModel, rCtrlSource ) )
+ {
+ lclPrepareConverter( maAddressConverter, mxDocModel, rCtrlSource, nRefSheet, false );
+ if( !maAddressConverter.getProperty( aAddress, PROP_Address ) )
+ throw RuntimeException();
+ }
+
+ // create argument sequence
+ NamedValue aValue;
+ aValue.Name = CREATE_OUSTRING( "BoundCell" );
+ aValue.Value <<= aAddress;
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= aValue;
+
+ // create the CellValueBinding instance and set at the control model
+ Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW );
+ Reference< XValueBinding > xBinding( xFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.table.CellValueBinding" ), aArgs ), UNO_QUERY_THROW );
+ xBindable->setValueBinding( xBinding );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // list entry source
+ if( rRowSource.getLength() > 0 ) try
+ {
+ // first check if the XListEntrySink interface is supported
+ Reference< XListEntrySink > xEntrySink( rxCtrlModel, UNO_QUERY_THROW );
+
+ // convert address string to cell range address struct
+ CellRangeAddress aRangeAddr;
+ if( !lclExtractRangeFromName( aRangeAddr, mxDocModel, rRowSource ) )
+ {
+ lclPrepareConverter( maRangeConverter, mxDocModel, rRowSource, nRefSheet, true );
+ if( !maRangeConverter.getProperty( aRangeAddr, PROP_Address ) )
+ throw RuntimeException();
+ }
+
+ // create argument sequence
+ NamedValue aValue;
+ aValue.Name = CREATE_OUSTRING( "CellRange" );
+ aValue.Value <<= aRangeAddr;
+ Sequence< Any > aArgs( 1 );
+ aArgs[ 0 ] <<= aValue;
+
+ // create the EntrySource instance and set at the control model
+ Reference< XMultiServiceFactory > xFactory( mxDocModel, UNO_QUERY_THROW );
+ Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.table.CellRangeListSource" ), aArgs ), UNO_QUERY_THROW );
+ xEntrySink->setListEntrySource( xEntrySource );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
// ActiveX (Forms 2.0) specific conversion ------------------------------------
void ControlConverter::convertAxBackground( PropertyMap& rPropMap,
@@ -432,14 +564,16 @@ OUString ControlModelBase::getServiceName() const
case API_CONTROL_FIXEDTEXT: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlFixedTextModel" );
case API_CONTROL_IMAGE: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlImageControlModel" );
case API_CONTROL_CHECKBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlCheckBoxModel" );
- case API_CONTROL_RADIOBUTTON: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlRadioButtonModel" );
+ case API_CONTROL_RADIOBUTTON: return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
case API_CONTROL_EDIT: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlEditModel" );
- case API_CONTROL_LISTBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlListBoxModel" );
- case API_CONTROL_COMBOBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlComboBoxModel" );
- case API_CONTROL_SPINBUTTON: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlSpinButtonModel" );
- case API_CONTROL_SCROLLBAR: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlScrollBarModel" );
+ case API_CONTROL_LISTBOX: return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
+ case API_CONTROL_COMBOBOX: return CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" );
+ case API_CONTROL_SPINBUTTON: return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
+ case API_CONTROL_SCROLLBAR: return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
case API_CONTROL_PROGRESSBAR: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlProgressBarModel" );
- case API_CONTROL_GROUPBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlGroupBoxModel" );
+ case API_CONTROL_FRAME: return CREATE_OUSTRING( "com.sun.star.awt.UnoFrameModel" );
+ case API_CONTROL_PAGE: return CREATE_OUSTRING( "com.sun.star.awt.UnoPageModel" );
+ case API_CONTROL_MULTIPAGE: return CREATE_OUSTRING( "com.sun.star.awt.UnoMultiPageModel" );
case API_CONTROL_DIALOG: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlDialogModel" );
default: OSL_ENSURE( false, "ControlModelBase::getServiceName - no AWT model service supported" );
}
@@ -1418,7 +1552,8 @@ ApiControlType AxTabStripModel::getControlType() const
void AxTabStripModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
{
rPropMap.setProperty( PROP_Decoration, mnTabStyle != AX_TABSTRIP_NONE );
- rPropMap.setProperty( PROP_MultiPageValue, mnSelectedTab );
+ // adjust for openoffice ( 1 based )
+ rPropMap.setProperty( PROP_MultiPageValue, mnSelectedTab + 1);
rConv.convertColor( rPropMap, PROP_BackgroundColor, mnBackColor );
AxFontDataModel::convertProperties( rPropMap, rConv );
}
@@ -1542,7 +1677,7 @@ AxFrameModel::AxFrameModel() :
ApiControlType AxFrameModel::getControlType() const
{
- return API_CONTROL_GROUPBOX;
+ return mbAwtModel ? API_CONTROL_FRAME : API_CONTROL_GROUPBOX;
}
void AxFrameModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const
@@ -1684,10 +1819,10 @@ bool EmbeddedControl::convertProperties( const Reference< XControlModel >& rxCtr
// ============================================================================
-EmbeddedForm::EmbeddedForm( const Reference< XMultiServiceFactory >& rxModelFactory,
+EmbeddedForm::EmbeddedForm( const Reference< XModel >& rxDocModel,
const Reference< XDrawPage >& rxDrawPage, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
- ControlConverter( rGraphicHelper, bDefaultColorBgr ),
- mxModelFactory( rxModelFactory ),
+ ControlConverter( rxDocModel, rGraphicHelper, bDefaultColorBgr ),
+ mxModelFactory( rxDocModel, UNO_QUERY ),
mxFormsSupp( rxDrawPage, UNO_QUERY )
{
OSL_ENSURE( mxModelFactory.is(), "EmbeddedForm::EmbeddedForm - missing service factory" );
diff --git a/oox/source/ole/makefile.mk b/oox/source/ole/makefile.mk
index 4e01392d4a57..a5232247cfa5 100644
--- a/oox/source/ole/makefile.mk
+++ b/oox/source/ole/makefile.mk
@@ -51,7 +51,8 @@ SLOFILES = \
$(SLO)$/vbahelper.obj \
$(SLO)$/vbainputstream.obj \
$(SLO)$/vbamodule.obj \
- $(SLO)$/vbaproject.obj
+ $(SLO)$/vbaproject.obj \
+ $(SLO)$/vbaprojectfilter.obj
# --- Targets -------------------------------------------------------
diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx
index 386c1a034641..4a42f7043aaf 100755
--- a/oox/source/ole/vbacontrol.cxx
+++ b/oox/source/ole/vbacontrol.cxx
@@ -27,17 +27,16 @@
************************************************************************/
#include "oox/ole/vbacontrol.hxx"
+
#include <algorithm>
#include <set>
-#include <rtl/ustrbuf.hxx>
#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/io/XInputStreamProvider.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
+#include <rtl/ustrbuf.hxx>
#include <xmlscript/xmldlg_imexp.hxx>
-#include "properties.hxx"
-#include "tokens.hxx"
#include "oox/helper/attributelist.hxx"
#include "oox/helper/binaryinputstream.hxx"
#include "oox/helper/propertymap.hxx"
@@ -45,26 +44,26 @@
#include "oox/helper/storagebase.hxx"
#include "oox/helper/textinputstream.hxx"
#include "oox/ole/vbahelper.hxx"
-
-using ::rtl::OUString;
-using ::rtl::OUStringBuffer;
-using ::com::sun::star::awt::XControlModel;
-using ::com::sun::star::container::XNameContainer;
-using ::com::sun::star::io::XInputStreamProvider;
-using ::com::sun::star::lang::XMultiServiceFactory;
-using ::com::sun::star::uno::Any;
-using ::com::sun::star::uno::Exception;
-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;
+#include "properties.hxx"
+#include "tokens.hxx"
namespace oox {
namespace ole {
// ============================================================================
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
namespace {
const sal_uInt16 VBA_SITE_CLASSIDINDEX = 0x8000;
@@ -222,17 +221,11 @@ bool VbaSiteModel::importBinaryModel( BinaryInputStream& rInStrm )
aReader.skipUndefinedProperty();
aReader.readStringProperty( maToolTip );
aReader.skipStringProperty(); // license key
- aReader.readStringProperty( maLinkedCell );
- aReader.readStringProperty( maSourceRange );
+ aReader.readStringProperty( maControlSource );
+ aReader.readStringProperty( maRowSource );
return aReader.finalizeImport();
}
-void VbaSiteModel::moveRelative( const AxPairData& rDistance )
-{
- maPos.first += rDistance.first;
- maPos.second += rDistance.second;
-}
-
bool VbaSiteModel::isVisible() const
{
return getFlag( mnFlags, VBA_SITE_VISIBLE );
@@ -280,12 +273,12 @@ ControlModelRef VbaSiteModel::createControlModel( const AxClassTable& rClassTabl
case VBA_SITE_TEXTBOX: xCtrlModel.reset( new AxTextBoxModel ); break;
case VBA_SITE_LISTBOX: xCtrlModel.reset( new AxListBoxModel ); break;
case VBA_SITE_COMBOBOX: xCtrlModel.reset( new AxComboBoxModel ); break;
- case VBA_SITE_SPINBUTTON: /*xCtrlModel.reset( new AxSpinButtonModel );*/ break; // not supported (?)
+ case VBA_SITE_SPINBUTTON: xCtrlModel.reset( new AxSpinButtonModel ); break;
case VBA_SITE_SCROLLBAR: xCtrlModel.reset( new AxScrollBarModel ); break;
- case VBA_SITE_TABSTRIP: break; // not supported
+ case VBA_SITE_TABSTRIP: xCtrlModel.reset( new AxTabStripModel ); break;
case VBA_SITE_FRAME: xCtrlModel.reset( new AxFrameModel ); break;
- case VBA_SITE_MULTIPAGE: break; // not supported
- case VBA_SITE_FORM: break; // not supported
+ case VBA_SITE_MULTIPAGE: xCtrlModel.reset( new AxMultiPageModel ); break;
+ case VBA_SITE_FORM: xCtrlModel.reset( new AxFormPageModel ); break;
default: OSL_ENSURE( false, "VbaSiteModel::createControlModel - unknown type index" );
}
}
@@ -339,6 +332,11 @@ void VbaSiteModel::convertProperties( PropertyMap& rPropMap,
}
}
+void VbaSiteModel::bindToSources( const Reference< XControlModel >& rxCtrlModel, const ControlConverter& rConv ) const
+{
+ rConv.bindToSources( rxCtrlModel, maControlSource, maRowSource );
+}
+
// ============================================================================
VbaFormControl::VbaFormControl()
@@ -445,11 +443,9 @@ void VbaFormControl::importStorage( StorageBase& rStrg, const AxClassTable& rCla
maControls.forEachMem( &VbaFormControl::importModelOrStorage,
::boost::ref( aOStrm ), ::boost::ref( rStrg ), ::boost::cref( maClassTable ) );
- /* Reorder the controls (sorts all option buttons of an option
- group together), and move all children of all embedded frames
- (group boxes) to this control (UNO group boxes cannot contain
- other controls). */
- finalizeEmbeddedControls();
+ /** Final processing on the control and all embedded controls,
+ depending on the type of this control. */
+ finalizeEmbeddedControls( rStrg );
}
}
}
@@ -471,6 +467,9 @@ bool VbaFormControl::convertProperties( const Reference< XControlModel >& rxCtrl
PropertySet aPropSet( rxCtrlModel );
aPropSet.setProperties( aPropMap );
+ // bind to control source and row source range
+ mxSiteModel->bindToSources( rxCtrlModel, rConv );
+
// create and convert all embedded controls
if( !maControls.empty() ) try
{
@@ -553,138 +552,182 @@ bool VbaFormControl::importEmbeddedSiteModels( BinaryInputStream& rInStrm )
return bValid;
}
-void VbaFormControl::finalizeEmbeddedControls()
-{
- /* This function performs two tasks:
-
- 1) Reorder the controls appropriately (sort all option buttons of an
- option group together to make grouping work).
- 2) Move all children of all embedded frames (group boxes) to this
- control (UNO group boxes cannot contain other controls).
- */
-
- // first, sort all controls by original tab index
- ::std::sort( maControls.begin(), maControls.end(), &compareByTabIndex );
-
- /* Collect the programmatical names of all embedded controls (needed to be
- able to set unused names to new dummy controls created below). Also
- collect the names of all children of embedded frames (group boxes).
- Luckily, names of controls must be unique in the entire form, not just
- in the current container. */
- VbaControlNamesSet aControlNames;
- VbaControlNameInserter aInserter( aControlNames );
- maControls.forEach( aInserter );
- for( VbaFormControlVector::iterator aIt = maControls.begin(), aEnd = maControls.end(); aIt != aEnd; ++aIt )
- if( (*aIt)->mxCtrlModel.get() && ((*aIt)->mxCtrlModel->getControlType() == API_CONTROL_GROUPBOX) )
- (*aIt)->maControls.forEach( aInserter );
-
- /* Reprocess the sorted list and collect all option button controls that
- are part of the same option group (determined by group name). All
- controls will be stored in a vector of vectors, that collects every
- option button group in one vector element, and other controls between
- these option groups (or leading or trailing controls) in other vector
- elements. If an option button group follows another group, a dummy
- separator control has to be inserted. */
- typedef RefVector< VbaFormControlVector > VbaFormControlVectorVector;
- VbaFormControlVectorVector aControlGroups;
-
- typedef RefMap< OUString, VbaFormControlVector > VbaFormControlVectorMap;
- VbaFormControlVectorMap aOptionGroups;
-
- typedef VbaFormControlVectorMap::mapped_type VbaFormControlVectorRef;
- bool bLastWasOptionButton = false;
- for( VbaFormControlVector::iterator aIt = maControls.begin(), aEnd = maControls.end(); aIt != aEnd; ++aIt )
+void VbaFormControl::finalizeEmbeddedControls( StorageBase& rStrg )
+{
+ /* Store all embedded controls in a temporary vector, so "exit on error"
+ will leave this control empty. */
+ VbaFormControlVector aControls;
+ aControls.swap( maControls );
+
+ /* If this is a multipage control, it stores additional data in the 'x'
+ stream of its storage. It contains the control identifiers of the form
+ page controls that contain the embedded controls of each page.
+ Additionally, the order of these pages is stored there (they are not
+ nessecarily in the order they are persisted in). */
+ if( AxMultiPageModel* pMultiPageModel = dynamic_cast< AxMultiPageModel* >( mxCtrlModel.get() ) )
{
- VbaFormControlRef xControl = *aIt;
- const ControlModelBase* pCtrlModel = xControl->mxCtrlModel.get();
+ // read additional attributes from the 'x' stream
+ BinaryXInputStream aXStrm( rStrg.openInputStream( CREATE_OUSTRING( "x" ) ), true );
+ OSL_ENSURE( !aXStrm.isEof(), "VbaFormControl::finalizeEmbeddedControls - missing 'x' stream" );
+ if( aXStrm.isEof() ) return;
- if( const AxOptionButtonModel* pOptButtonModel = dynamic_cast< const AxOptionButtonModel* >( pCtrlModel ) )
+ // skip the page property structures related to all controls
+ for( size_t nSiteIdx = 0, nSiteCount = aControls.size(); nSiteIdx < nSiteCount; ++nSiteIdx )
{
- // check if a new option group needs to be created
- const OUString& rGroupName = pOptButtonModel->getGroupName();
- VbaFormControlVectorRef& rxOptionGroup = aOptionGroups[ rGroupName ];
- if( !rxOptionGroup )
- {
- /* If last control was an option button too, we have two
- option groups following each other, so a dummy separator
- control is needed. */
- if( bLastWasOptionButton )
- {
- VbaFormControlVectorRef xDummyGroup( new VbaFormControlVector );
- aControlGroups.push_back( xDummyGroup );
- OUString aName = aControlNames.generateDummyName();
- VbaFormControlRef xDummyControl( new VbaDummyFormControl( aName ) );
- xDummyGroup->push_back( xDummyControl );
- }
- rxOptionGroup.reset( new VbaFormControlVector );
- aControlGroups.push_back( rxOptionGroup );
- }
- /* Append the option button to the control group (which is now
- referred by the vector aControlGroups and by the map
- aOptionGroups). */
- rxOptionGroup->push_back( xControl );
- bLastWasOptionButton = true;
+ AxBinaryPropertyReader aReader( aXStrm );
+ aReader.skipUndefinedProperty();
+ aReader.skipIntProperty< sal_uInt32 >(); // transition effect
+ aReader.skipIntProperty< sal_uInt32 >(); // transition period
+ if( !aReader.finalizeImport() ) return;
}
- else
- {
- // open a new control group, if the last group is an option group
- if( bLastWasOptionButton || aControlGroups.empty() )
- {
- VbaFormControlVectorRef xControlGroup( new VbaFormControlVector );
- aControlGroups.push_back( xControlGroup );
- }
- // append the control to the last control group
- VbaFormControlVector& rLastGroup = *aControlGroups.back();
- rLastGroup.push_back( xControl );
- bLastWasOptionButton = false;
- // if control is a group box, move all its children to this control
- if( pCtrlModel && (pCtrlModel->getControlType() == API_CONTROL_GROUPBOX) )
+ // read the multipage property structure containing a list of page IDs
+ sal_Int32 nPageCount = 0;
+ sal_Int32 nTabStripId = 0;
+ AxBinaryPropertyReader aReader( aXStrm );
+ aReader.skipUndefinedProperty();
+ aReader.readIntProperty< sal_Int32 >( nPageCount );
+ aReader.readIntProperty< sal_Int32 >( nTabStripId );
+ if( !aReader.finalizeImport() ) return;
+ // read the array containing all page identifiers in current order
+ typedef ::std::vector< sal_Int32 > AxPageIdVector;
+ AxPageIdVector aPageIds;
+ for( sal_Int32 nPage = 0; !aXStrm.isEof() && (nPage < nPageCount); ++nPage )
+ aPageIds.push_back( aXStrm.readInt32() );
+ if( aXStrm.isEof() ) return;
+
+ // check the page count value
+ bool bValidPageCount = (0 < nPageCount) && (static_cast< size_t >( nPageCount + 1 ) == aControls.size());
+ OSL_ENSURE( bValidPageCount, "VbaFormControl::finalizeEmbeddedControls - invalid number of pages" );
+ if( !bValidPageCount ) return;
+
+ /* Check that this multipage contains the expected controls:
+ - a tabstrip control, specified by nTabStripId,
+ - form page controls (containing the embedded controls of each page). */
+
+ // the controls may be in arbitrary order, first map them by ID
+ RefMap< sal_Int32, VbaFormControl > aControlsById;
+ for( VbaFormControlVector::iterator aIt = aControls.begin(), aEnd = aControls.end(); aIt != aEnd; ++aIt )
+ {
+ VbaFormControlRef xControl = *aIt;
+ sal_Int32 nId = xControl->getControlId();
+ OSL_ENSURE( (nId > 0) && !aControlsById.has( nId ), "VbaFormControl::finalizeEmbeddedControls - invalid control ID" );
+ aControlsById[ nId ] = xControl;
+ }
+ // store tabstrip in the multipage, it will care about property conversion
+ AxTabStripModelRef xTabStripModel;
+ VbaFormControlRef xControl = aControlsById.get( nTabStripId );
+ if( xControl.get() )
+ xTabStripModel = ::boost::dynamic_pointer_cast< AxTabStripModel >( xControl->mxCtrlModel );
+ OSL_ENSURE( xTabStripModel.get(), "VbaFormControl::finalizeEmbeddedControls - missing tabstrip control" );
+ if( !xTabStripModel ) return;
+ pMultiPageModel->setTabStripModel( xTabStripModel );
+ aControlsById.erase( nTabStripId );
+ // store all pages in maControls in the correct order specified by aPageIds
+ sal_Int32 nTabIndex = 0;
+ for( AxPageIdVector::iterator aIt = aPageIds.begin(), aEnd = aPageIds.end(); aIt != aEnd; ++aIt, ++nTabIndex )
+ {
+ VbaFormControlRef rControl = aControlsById.get( *aIt );
+ AxFormPageModel* pFormPageModel = rControl.get() ? dynamic_cast< AxFormPageModel* >( rControl->mxCtrlModel.get() ) : 0;
+ OSL_ENSURE( pFormPageModel, "VbaFormControl::finalizeEmbeddedControls - missing formpage control" );
+ // do not exit on error but try to collect as much pages as possible
+ if( pFormPageModel )
{
- /* Move all embedded controls of the group box relative to the
- position of the group box. */
- xControl->moveEmbeddedToAbsoluteParent();
- /* Insert all children of the group box into the last control
- group (following the group box). */
- rLastGroup.insert( rLastGroup.end(), xControl->maControls.begin(), xControl->maControls.end() );
- xControl->maControls.clear();
- // check if last control of the group box is an option button
- bLastWasOptionButton = dynamic_cast< const AxOptionButtonModel* >( rLastGroup.back()->mxCtrlModel.get() ) != 0;
+ // get the tab caption from tabstrip control and set it at the formpage
+ OUString aCaption = xTabStripModel->getCaption( nTabIndex );
+ pFormPageModel->importProperty( XML_Caption, aCaption );
+ // store the control in maControls
+ maControls.push_back( rControl );
+ aControlsById.erase( *aIt );
}
}
}
-
- // flatten the vector of vectors of form controls to a single vector
- maControls.clear();
- for( VbaFormControlVectorVector::iterator aIt = aControlGroups.begin(), aEnd = aControlGroups.end(); aIt != aEnd; ++aIt )
- maControls.insert( maControls.end(), (*aIt)->begin(), (*aIt)->end() );
-}
-
-void VbaFormControl::moveRelative( const AxPairData& rDistance )
-{
- if( mxSiteModel.get() )
- mxSiteModel->moveRelative( rDistance );
-}
-
-void VbaFormControl::moveEmbeddedToAbsoluteParent()
-{
- if( mxSiteModel.get() && !maControls.empty() )
+ else
{
- // distance to move is equal to position of this control in its parent
- AxPairData aDistance = mxSiteModel->getPosition();
-
- /* For group boxes: add half of the font height to Y position (VBA
- positions relative to frame border line, not to 'top' of frame). */
- const AxFontDataModel* pFontModel = dynamic_cast< const AxFontDataModel* >( mxCtrlModel.get() );
- if( pFontModel && (pFontModel->getControlType() == API_CONTROL_GROUPBOX) )
+ /* Reorder the controls appropriately (sort all option buttons of an
+ option group together to make grouping work), and erase all plain
+ tabstrip controls (currently not supported in UNO dialogs). */
+
+ // first, sort all controls by original tab index
+ ::std::sort( aControls.begin(), aControls.end(), &compareByTabIndex );
+
+ /* Collect the programmatical names of all embedded controls (needed to be
+ able to set unused names to new dummy controls created below). */
+ VbaControlNamesSet aControlNames;
+ VbaControlNameInserter aInserter( aControlNames );
+ aControls.forEach( aInserter );
+
+ /* Reprocess the sorted list and collect all option button controls that
+ are part of the same option group (determined by group name). All
+ controls will be stored in a vector of vectors, that collects every
+ option button group in one vector element, and other controls between
+ these option groups (or leading or trailing controls) in other vector
+ elements. If an option button group follows another group, a dummy
+ separator control has to be inserted. */
+ typedef RefVector< VbaFormControlVector > VbaFormControlVectorVector;
+ VbaFormControlVectorVector aControlGroups;
+
+ typedef RefMap< OUString, VbaFormControlVector > VbaFormControlVectorMap;
+ VbaFormControlVectorMap aOptionGroups;
+
+ typedef VbaFormControlVectorMap::mapped_type VbaFormControlVectorRef;
+ bool bLastWasOptionButton = false;
+ for( VbaFormControlVector::iterator aIt = aControls.begin(), aEnd = aControls.end(); aIt != aEnd; ++aIt )
{
- // convert points to 1/100 mm (1 pt = 1/72 inch = 2.54/72 cm = 2540/72 1/100 mm)
- sal_Int32 nFontHeight = static_cast< sal_Int32 >( pFontModel->getFontHeight() * 2540 / 72 );
- aDistance.second += nFontHeight / 2;
+ VbaFormControlRef xControl = *aIt;
+ const ControlModelBase* pCtrlModel = xControl->mxCtrlModel.get();
+ if ( !pCtrlModel ) // skip unsupported controls
+ continue;
+ if( const AxOptionButtonModel* pOptButtonModel = dynamic_cast< const AxOptionButtonModel* >( pCtrlModel ) )
+ {
+ // check if a new option group needs to be created
+ const OUString& rGroupName = pOptButtonModel->getGroupName();
+ VbaFormControlVectorRef& rxOptionGroup = aOptionGroups[ rGroupName ];
+ if( !rxOptionGroup )
+ {
+ /* If last control was an option button too, we have two
+ option groups following each other, so a dummy separator
+ control is needed. */
+ if( bLastWasOptionButton )
+ {
+ VbaFormControlVectorRef xDummyGroup( new VbaFormControlVector );
+ aControlGroups.push_back( xDummyGroup );
+ OUString aName = aControlNames.generateDummyName();
+ VbaFormControlRef xDummyControl( new VbaDummyFormControl( aName ) );
+ xDummyGroup->push_back( xDummyControl );
+ }
+ rxOptionGroup.reset( new VbaFormControlVector );
+ aControlGroups.push_back( rxOptionGroup );
+ }
+ /* Append the option button to the control group (which is now
+ referred by the vector aControlGroups and by the map
+ aOptionGroups). */
+ rxOptionGroup->push_back( xControl );
+ bLastWasOptionButton = true;
+ }
+ else
+ {
+ // skip unsupported controls (tabstrips and page controls)
+ ApiControlType eCtrlType = pCtrlModel->getControlType();
+ if( (eCtrlType != API_CONTROL_TABSTRIP) && (eCtrlType != API_CONTROL_PAGE) )
+ {
+ // open a new control group, if the last group is an option group
+ if( bLastWasOptionButton || aControlGroups.empty() )
+ {
+ VbaFormControlVectorRef xControlGroup( new VbaFormControlVector );
+ aControlGroups.push_back( xControlGroup );
+ }
+ // append the control to the last control group
+ VbaFormControlVector& rLastGroup = *aControlGroups.back();
+ rLastGroup.push_back( xControl );
+ bLastWasOptionButton = false;
+ }
+ }
}
- // move the embedded controls
- maControls.forEachMem( &VbaFormControl::moveRelative, ::boost::cref( aDistance ) );
+ // flatten the vector of vectors of form controls to a single vector
+ for( VbaFormControlVectorVector::iterator aIt = aControlGroups.begin(), aEnd = aControlGroups.end(); aIt != aEnd; ++aIt )
+ maControls.insert( maControls.end(), (*aIt)->begin(), (*aIt)->end() );
}
}
@@ -753,9 +796,10 @@ bool lclEatKeyword( OUString& rCodeLine, const OUString& rKeyword )
// ----------------------------------------------------------------------------
VbaUserForm::VbaUserForm( const Reference< XMultiServiceFactory >& rxGlobalFactory,
- const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
- ControlConverter( rGraphicHelper, bDefaultColorBgr ),
- mxGlobalFactory( rxGlobalFactory )
+ const Reference< XModel >& rxDocModel, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) :
+ mxGlobalFactory( rxGlobalFactory ),
+ mxDocModel( rxDocModel ),
+ maConverter( rxDocModel, rGraphicHelper, bDefaultColorBgr )
{
OSL_ENSURE( mxGlobalFactory.is(), "VbaUserForm::VbaUserForm - missing service factory" );
}
@@ -764,7 +808,7 @@ void VbaUserForm::importForm( const Reference< XModel >& rxDocModel, const Refer
StorageBase& rVbaFormStrg, const OUString& rModuleName, rtl_TextEncoding eTextEnc )
{
OSL_ENSURE( rxDialogLib.is(), "VbaUserForm::importForm - missing dialog library" );
- if( !mxGlobalFactory.is() || !rxDialogLib.is() )
+ if( !mxGlobalFactory.is() || !mxDocModel.is() || !rxDialogLib.is() )
return;
// check that the '03VBFrame' stream exists, this is required for forms
@@ -826,7 +870,7 @@ void VbaUserForm::importForm( const Reference< XModel >& rxDocModel, const Refer
Reference< XNameContainer > xDialogNC( xDialogModel, UNO_QUERY_THROW );
// convert properties and embedded controls
- if( convertProperties( xDialogModel, *this, 0 ) )
+ if( convertProperties( xDialogModel, maConverter, 0 ) )
{
// export the dialog to XML and insert it into the dialog library
PropertySet aFactoryProps( mxGlobalFactory );
diff --git a/oox/source/ole/vbamodule.cxx b/oox/source/ole/vbamodule.cxx
index d8c528b1bfc0..310f86572ce8 100644
--- a/oox/source/ole/vbamodule.cxx
+++ b/oox/source/ole/vbamodule.cxx
@@ -27,29 +27,101 @@
************************************************************************/
#include "oox/ole/vbamodule.hxx"
+#include <hash_map>
#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/script/ModuleInfo.hpp>
#include <com/sun/star/script/ModuleType.hpp>
#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
+#include <cppuhelper/implbase1.hxx>
#include "oox/helper/binaryinputstream.hxx"
#include "oox/helper/storagebase.hxx"
#include "oox/helper/textinputstream.hxx"
#include "oox/ole/vbahelper.hxx"
#include "oox/ole/vbainputstream.hxx"
-using ::rtl::OUString;
-using ::rtl::OUStringBuffer;
+namespace oox {
+namespace ole {
+
+// ============================================================================
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::script::vba;
using namespace ::com::sun::star::uno;
-namespace oox {
-namespace ole {
-
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
// ============================================================================
+typedef ::cppu::WeakImplHelper1< XIndexContainer > OleIdToNameContainer_BASE;
+typedef std::hash_map< sal_Int32, rtl::OUString > ObjIdToName;
+
+class OleIdToNameContainer : public OleIdToNameContainer_BASE
+{
+ ObjIdToName ObjIdToNameHash;
+ ::osl::Mutex m_aMutex;
+ bool hasByIndex( ::sal_Int32 Index )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return ( ObjIdToNameHash.find( Index ) != ObjIdToNameHash.end() );
+ }
+public:
+ OleIdToNameContainer() {}
+ // XIndexContainer Methods
+ virtual void SAL_CALL insertByIndex( ::sal_Int32 Index, const Any& Element ) throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ rtl::OUString sOleName;
+ if ( !( Element >>= sOleName ) )
+ throw IllegalArgumentException();
+ ObjIdToNameHash[ Index ] = sOleName;
+ }
+ virtual void SAL_CALL removeByIndex( ::sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !hasByIndex( Index ) )
+ throw IndexOutOfBoundsException();
+ ObjIdToNameHash.erase( ObjIdToNameHash.find( Index ) );
+ }
+ // XIndexReplace Methods
+ virtual void SAL_CALL replaceByIndex( ::sal_Int32 Index, const Any& Element ) throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !hasByIndex( Index ) )
+ throw IndexOutOfBoundsException();
+ rtl::OUString sOleName;
+ if ( !( Element >>= sOleName ) )
+ throw IllegalArgumentException();
+ ObjIdToNameHash[ Index ] = sOleName;
+ }
+ // XIndexAccess Methods
+ virtual ::sal_Int32 SAL_CALL getCount( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return ObjIdToNameHash.size();
+ }
+ virtual Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !hasByIndex( Index ) )
+ throw IndexOutOfBoundsException();
+ return makeAny( ObjIdToNameHash[ Index ] );
+ }
+ // XElementAccess Methods
+ virtual Type SAL_CALL getElementType( ) throw (RuntimeException)
+ {
+ return ::getCppuType( static_cast< const ::rtl::OUString* >( 0 ) );
+ }
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ return ( getCount() > 0 );
+ }
+};
+
+ // ============================================================================
VbaModule::VbaModule( const Reference< XModel >& rxDocModel, const OUString& rName, rtl_TextEncoding eTextEnc, bool bExecutable ) :
mxDocModel( rxDocModel ),
@@ -129,18 +201,86 @@ void VbaModule::importDirRecords( BinaryInputStream& rDirStrm )
OSL_ENSURE( mnOffset < SAL_MAX_UINT32, "VbaModule::importDirRecords - missing module stream offset" );
}
-void VbaModule::importSourceCode( StorageBase& rVbaStrg,
- const Reference< XNameContainer >& rxBasicLib, const Reference< XNameAccess >& rxDocObjectNA ) const
+void VbaModule::createAndImportModule( StorageBase& rVbaStrg, const Reference< XNameContainer >& rxBasicLib,
+ const Reference< XNameAccess >& rxDocObjectNA, const Reference< XNameContainer >& rxOleNameOverrides ) const
{
- if( (maName.getLength() == 0) || (maStreamName.getLength() == 0) || (mnOffset == SAL_MAX_UINT32) )
- return;
+ OUString aVBASourceCode = readSourceCode( rVbaStrg, rxOleNameOverrides );
+ createModule( aVBASourceCode, rxBasicLib, rxDocObjectNA );
+}
+
+void VbaModule::createEmptyModule( const Reference< XNameContainer >& rxBasicLib, const Reference< XNameAccess >& rxDocObjectNA ) const
+{
+ createModule( OUString(), rxBasicLib, rxDocObjectNA );
+}
- BinaryXInputStream aInStrm( rVbaStrg.openInputStream( maStreamName ), true );
- OSL_ENSURE( !aInStrm.isEof(), "VbaModule::importSourceCode - cannot open module stream" );
- // skip the 'performance cache' stored before the actual source code
- aInStrm.seek( mnOffset );
- // if stream is still valid, load the source code
- if( aInStrm.isEof() )
+// private --------------------------------------------------------------------
+
+OUString VbaModule::readSourceCode( StorageBase& rVbaStrg, const Reference< XNameContainer >& rxOleNameOverrides ) const
+{
+ OUStringBuffer aSourceCode;
+ if( (maStreamName.getLength() > 0) && (mnOffset != SAL_MAX_UINT32) )
+ {
+ BinaryXInputStream aInStrm( rVbaStrg.openInputStream( maStreamName ), true );
+ OSL_ENSURE( !aInStrm.isEof(), "VbaModule::readSourceCode - cannot open module stream" );
+ // skip the 'performance cache' stored before the actual source code
+ aInStrm.seek( mnOffset );
+ // if stream is still valid, load the source code
+ if( !aInStrm.isEof() )
+ {
+ // decompression starts at current stream position of aInStrm
+ VbaInputStream aVbaStrm( aInStrm );
+ // load the source code line-by-line, with some more processing
+ TextInputStream aVbaTextStrm( aVbaStrm, meTextEnc );
+ while( !aVbaTextStrm.isEof() )
+ {
+ OUString aCodeLine = aVbaTextStrm.readLine();
+ if( aCodeLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "Attribute " ) ) )
+ {
+ // attribute
+ extractOleOverrideFromAttr( aCodeLine, rxOleNameOverrides );
+ }
+ else
+ {
+ // normal source code line
+ if( !mbExecutable )
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem " ) );
+ aSourceCode.append( aCodeLine ).append( sal_Unicode( '\n' ) );
+ }
+ }
+ }
+ }
+ return aSourceCode.makeStringAndClear();
+}
+
+void VbaModule::extractOleOverrideFromAttr( const OUString& rAttribute, const Reference< XNameContainer >& rxOleNameOverrides ) const
+{
+ // 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"
+ OUString sControlAttribute = CREATE_OUSTRING( "Attribute VB_Control = \"" );
+ if ( rxOleNameOverrides.is() && rAttribute.indexOf( sControlAttribute ) != -1 )
+ {
+ OUString sRest = rAttribute.copy( sControlAttribute.getLength() );
+ sal_Int32 nPos = sRest.indexOf( ',' );
+ OUString sCntrlName = sRest.copy( 0, nPos );
+
+ sal_Int32 nCntrlId = sRest.copy( nPos + 1 ).copy( 0, sRest.indexOf( ',', nPos + 1) ).toInt32();
+ OSL_TRACE("In module %s, assiging %d controlname %s",
+ rtl::OUStringToOString( maName, RTL_TEXTENCODING_UTF8 ).getStr(), nCntrlId,
+ rtl::OUStringToOString( sCntrlName, RTL_TEXTENCODING_UTF8 ).getStr() );
+ if ( !rxOleNameOverrides->hasByName( maName ) )
+ rxOleNameOverrides->insertByName( maName, Any( Reference< XIndexContainer> ( new OleIdToNameContainer ) ) );
+ Reference< XIndexContainer > xIdToOleName;
+ if ( rxOleNameOverrides->getByName( maName ) >>= xIdToOleName )
+ xIdToOleName->insertByIndex( nCntrlId, makeAny( sCntrlName ) );
+ }
+}
+
+void VbaModule::createModule( const OUString& rVBASourceCode,
+ const Reference< XNameContainer >& rxBasicLib, const Reference< XNameAccess >& rxDocObjectNA ) const
+{
+ if( maName.getLength() == 0 )
return;
// prepare the Basic module
@@ -189,21 +329,8 @@ void VbaModule::importSourceCode( StorageBase& rVbaStrg,
append( maName.replace( ' ', '_' ) ).append( sal_Unicode( '\n' ) );
}
- // decompression starts at current stream position of aInStrm
- VbaInputStream aVbaStrm( aInStrm );
- // load the source code line-by-line, with some more processing
- TextInputStream aVbaTextStrm( aVbaStrm, meTextEnc );
- while( !aVbaTextStrm.isEof() )
- {
- OUString aCodeLine = aVbaTextStrm.readLine();
- // skip all 'Attribute' statements
- if( !aCodeLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "Attribute " ) ) )
- {
- if( !mbExecutable )
- aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem " ) );
- aSourceCode.append( aCodeLine ).append( sal_Unicode( '\n' ) );
- }
- }
+ // append passed VBA source code
+ aSourceCode.append( rVBASourceCode );
// close the subroutine named after the module
if( !mbExecutable )
@@ -226,7 +353,7 @@ void VbaModule::importSourceCode( StorageBase& rVbaStrg,
}
catch( Exception& )
{
- OSL_ENSURE( false, "VbaModule::importSourceCode - cannot insert module into library" );
+ OSL_ENSURE( false, "VbaModule::createModule - cannot insert module into library" );
}
}
diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx
index fad2dba04ffa..f8acf017135b 100755
--- a/oox/source/ole/vbaproject.cxx
+++ b/oox/source/ole/vbaproject.cxx
@@ -130,11 +130,9 @@ VbaProject::VbaProject( const Reference< XMultiServiceFactory >& rxGlobalFactory
VbaFilterConfig( rxGlobalFactory, rConfigCompName ),
mxGlobalFactory( rxGlobalFactory ),
mxDocModel( rxDocModel ),
- maLibName( CREATE_OUSTRING( "Standard" ) )
+ maPrjName( CREATE_OUSTRING( "Standard" ) )
{
OSL_ENSURE( mxDocModel.is(), "VbaProject::VbaProject - missing document model" );
- mxBasicLib = openLibrary( PROP_BasicLibraries, false );
- mxDialogLib = openLibrary( PROP_DialogLibraries, false );
}
VbaProject::~VbaProject()
@@ -174,6 +172,18 @@ bool VbaProject::hasDialog( const OUString& rDialogName ) const
return mxDialogLib.is() && mxDialogLib->hasByName( rDialogName );
}
+// protected ------------------------------------------------------------------
+
+void VbaProject::addDummyModule( const OUString& rName, sal_Int32 nType )
+{
+ OSL_ENSURE( rName.getLength() > 0, "VbaProject::addDummyModule - missing module name" );
+ maDummyModules[ rName ] = nType;
+}
+
+void VbaProject::prepareModuleImport()
+{
+}
+
// private --------------------------------------------------------------------
Reference< XLibraryContainer > VbaProject::getLibraryContainer( sal_Int32 nPropId )
@@ -189,9 +199,9 @@ Reference< XNameContainer > VbaProject::openLibrary( sal_Int32 nPropId, bool bCr
try
{
Reference< XLibraryContainer > xLibContainer( getLibraryContainer( nPropId ), UNO_SET_THROW );
- if( bCreateMissing && !xLibContainer->hasByName( maLibName ) )
- xLibContainer->createLibrary( maLibName );
- xLibrary.set( xLibContainer->getByName( maLibName ), UNO_QUERY_THROW );
+ if( bCreateMissing && !xLibContainer->hasByName( maPrjName ) )
+ xLibContainer->createLibrary( maPrjName );
+ xLibrary.set( xLibContainer->getByName( maPrjName ), UNO_QUERY_THROW );
}
catch( Exception& )
{
@@ -232,6 +242,9 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
if( aDirStrm.isEof() )
return;
+ // virtual call, derived classes may do some preparations
+ prepareModuleImport();
+
// read all records of the directory
rtl_TextEncoding eTextEnc = RTL_TEXTENCODING_MS_1252;
sal_uInt16 nModuleCount = 0;
@@ -260,6 +273,14 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
eTextEnc = eNewTextEnc;
}
break;
+ case VBA_ID_PROJECTNAME:
+ {
+ OUString aPrjName = aRecStrm.readCharArrayUC( nRecSize, eTextEnc );
+ OSL_ENSURE( aPrjName.getLength() > 0, "VbaProject::importVba - invalid project name" );
+ if( aPrjName.getLength() > 0 )
+ maPrjName = aPrjName;
+ }
+ break;
case VBA_ID_PROJECTMODULES:
OOX_ENSURE_RECORDSIZE( nRecSize == 2 );
OSL_ENSURE( aModules.empty(), "VbaProject::importVba - unexpected PROJECTMODULES record" );
@@ -346,11 +367,21 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
}
}
+ // create empty dummy modules
+ VbaModuleMap aDummyModules;
+ for( DummyModuleMap::iterator aIt = maDummyModules.begin(), aEnd = maDummyModules.end(); aIt != aEnd; ++aIt )
+ {
+ OSL_ENSURE( !aModules.has( aIt->first ) && !aDummyModules.has( aIt->first ), "VbaProject::importVba - multiple modules with the same name" );
+ VbaModuleMap::mapped_type& rxModule = aDummyModules[ aIt->first ];
+ rxModule.reset( new VbaModule( mxDocModel, aIt->first, eTextEnc, bExecutable ) );
+ rxModule->setType( aIt->second );
+ }
+
/* Now it is time to load the source code. All modules will be inserted
- into the Basic library of the document specified by the 'maLibName'
+ into the Basic library of the document specified by the 'maPrjName'
member. Do not create the Basic library, if there are no modules
specified. */
- if( !aModules.empty() ) try
+ if( !aModules.empty() || !aDummyModules.empty() ) try
{
// get the model factory and the basic library
Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW );
@@ -359,7 +390,10 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
// set library container to VBA compatibility mode
try
{
- Reference< XVBACompatibility >( getLibraryContainer( PROP_BasicLibraries ), UNO_QUERY_THROW )->setVBACompatibilityMode( sal_True );
+ Reference< XVBACompatibility > xVBACompat( getLibraryContainer( PROP_BasicLibraries ), UNO_QUERY_THROW );
+ xVBACompat->setVBACompatibilityMode( sal_True );
+ xVBACompat->setProjectName( maPrjName );
+
}
catch( Exception& )
{
@@ -385,10 +419,17 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
// not all documents support this
}
- // call Basic source code import for each module, boost::[c]ref enforces pass-by-ref
if( xBasicLib.is() )
- aModules.forEachMem( &VbaModule::importSourceCode,
- ::boost::ref( *xVbaStrg ), ::boost::cref( xBasicLib ), ::boost::cref( xDocObjectNA ) );
+ {
+ // call Basic source code import for each module, boost::[c]ref enforces pass-by-ref
+ aModules.forEachMem( &VbaModule::createAndImportModule,
+ ::boost::ref( *xVbaStrg ), ::boost::cref( xBasicLib ),
+ ::boost::cref( xDocObjectNA ), ::boost::cref( mxOleOverridesSink ) );
+
+ // create empty dummy modules
+ aDummyModules.forEachMem( &VbaModule::createEmptyModule,
+ ::boost::cref( xBasicLib ), ::boost::cref( xDocObjectNA ) );
+ }
}
catch( Exception& )
{
@@ -418,7 +459,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 );
+ VbaUserForm aForm( mxGlobalFactory, mxDocModel, rGraphicHelper, bDefaultColorBgr );
aForm.importForm( mxDocModel, xDialogLib, *xSubStrg, aModuleName, eTextEnc );
}
catch( Exception& )
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index 98f712fbedc6..e8c33b4fc71a 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -6,6 +6,7 @@ Adjust
AdjustContrast
AdjustLuminance
AdjustmentValues
+Address
Align
AnchorPosition
ArrangeOrder
@@ -334,6 +335,7 @@ RefX
RefY
Reference
ReferenceDevice
+ReferenceSheet
RegularExpressions
RelId
RelativeHorizontalTabbarWidth
@@ -463,5 +465,6 @@ Weight
WhiteDay
Width
WritingMode
+XLA1Representation
ZoomType
ZoomValue
diff --git a/oox/source/token/tokenmap.cxx b/oox/source/token/tokenmap.cxx
index d02a74807ec1..c62fe2277b52 100644
--- a/oox/source/token/tokenmap.cxx
+++ b/oox/source/token/tokenmap.cxx
@@ -33,8 +33,6 @@
#include "tokens.hxx"
#include "oox/helper/containerhelper.hxx"
-#include <string.h>
-
using ::rtl::OString;
using ::rtl::OUString;
using ::com::sun::star::uno::Sequence;
diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx
index 1e3bd0135b5e..61dfd4b6c362 100644
--- a/oox/source/vml/vmldrawing.cxx
+++ b/oox/source/vml/vmldrawing.cxx
@@ -103,7 +103,7 @@ Drawing::~Drawing()
{
if( !mxCtrlForm.get() )
mxCtrlForm.reset( new ::oox::ole::EmbeddedForm(
- mrFilter.getModelFactory(), mxDrawPage, mrFilter.getGraphicHelper() ) );
+ mrFilter.getModel(), mxDrawPage, mrFilter.getGraphicHelper() ) );
return *mxCtrlForm;
}
diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx
index ad6bb97cdea9..4a32fe5d42e1 100644
--- a/oox/source/xls/drawingfragment.cxx
+++ b/oox/source/xls/drawingfragment.cxx
@@ -28,44 +28,30 @@
#include "oox/xls/drawingfragment.hxx"
#include <com/sun/star/awt/Point.hpp>
-#include <com/sun/star/beans/NamedValue.hpp>
-#include <com/sun/star/form/binding/XBindableValue.hpp>
-#include <com/sun/star/form/binding/XListEntrySink.hpp>
-#include <com/sun/star/form/binding/XListEntrySource.hpp>
-#include <com/sun/star/form/binding/XValueBinding.hpp>
-#include "properties.hxx"
-#include "oox/helper/attributelist.hxx"
-#include "oox/helper/propertyset.hxx"
#include "oox/drawingml/connectorshapecontext.hxx"
#include "oox/drawingml/graphicshapecontext.hxx"
#include "oox/drawingml/shapecontext.hxx"
#include "oox/drawingml/shapegroupcontext.hxx"
+#include "oox/helper/attributelist.hxx"
+#include "oox/helper/propertyset.hxx"
#include "oox/vml/vmlshape.hxx"
#include "oox/vml/vmlshapecontainer.hxx"
#include "oox/xls/formulaparser.hxx"
#include "oox/xls/stylesbuffer.hxx"
#include "oox/xls/themebuffer.hxx"
#include "oox/xls/unitconverter.hxx"
+#include "properties.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::table;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
-using ::rtl::OUString;
-using ::com::sun::star::uno::Any;
-using ::com::sun::star::uno::Exception;
-using ::com::sun::star::uno::Reference;
-using ::com::sun::star::uno::Sequence;
-using ::com::sun::star::uno::UNO_QUERY;
-using ::com::sun::star::uno::UNO_QUERY_THROW;
-using ::com::sun::star::beans::NamedValue;
-using ::com::sun::star::awt::Point;
-using ::com::sun::star::awt::Rectangle;
-using ::com::sun::star::awt::Size;
-using ::com::sun::star::awt::XControlModel;
-using ::com::sun::star::form::binding::XBindableValue;
-using ::com::sun::star::form::binding::XListEntrySink;
-using ::com::sun::star::form::binding::XListEntrySource;
-using ::com::sun::star::form::binding::XValueBinding;
-using ::com::sun::star::drawing::XShape;
-using ::com::sun::star::table::CellAddress;
-using ::com::sun::star::table::CellRangeAddress;
using ::oox::core::ContextHandlerRef;
using ::oox::drawingml::ConnectorShapeContext;
using ::oox::drawingml::GraphicalObjectFrameContext;
@@ -74,10 +60,10 @@ using ::oox::drawingml::Shape;
using ::oox::drawingml::ShapePtr;
using ::oox::drawingml::ShapeContext;
using ::oox::drawingml::ShapeGroupContext;
-// no using's for ::oox::vml, that may clash with ::oox::drawingml types
+using ::rtl::OUString;
-namespace oox {
-namespace xls {
+
+// no using's for ::oox::vml, that may clash with ::oox::drawingml types
// ============================================================================
@@ -557,7 +543,8 @@ bool VmlFindNoteFunc::operator()( const ::oox::vml::ShapeBase& rShape ) const
VmlDrawing::VmlDrawing( const WorksheetHelper& rHelper ) :
::oox::vml::Drawing( rHelper.getOoxFilter(), rHelper.getDrawPage(), ::oox::vml::VMLDRAWING_EXCEL ),
- WorksheetHelper( rHelper )
+ WorksheetHelper( rHelper ),
+ maControlConv( rHelper.getBaseFilter().getModel(), rHelper.getBaseFilter().getGraphicHelper() )
{
}
@@ -592,65 +579,9 @@ void VmlDrawing::convertControlClientData( const Reference< XControlModel >& rxC
// printable
aPropSet.setProperty( PROP_Printable, rClientData.mbPrintObject );
- // linked cell
- if( rClientData.maLinkedCell.getLength() > 0 ) try
- {
- Reference< XBindableValue > xBindable( rxCtrlModel, UNO_QUERY_THROW );
-
- // convert formula string to cell address
- FormulaParser& rParser = getFormulaParser();
- TokensFormulaContext aContext( true, false );
- aContext.setBaseAddress( CellAddress( getSheetIndex(), 0, 0 ) );
- rParser.importFormula( aContext, rClientData.maLinkedCell );
- CellAddress aAddress;
- if( rParser.extractCellAddress( aAddress, aContext.getTokens(), true ) )
- {
- // create argument sequence for createInstanceWithArguments()
- NamedValue aValue;
- aValue.Name = CREATE_OUSTRING( "BoundCell" );
- aValue.Value <<= aAddress;
- Sequence< Any > aArgs( 1 );
- aArgs[ 0 ] <<= aValue;
-
- // create the CellValueBinding instance and set at the control model
- Reference< XValueBinding > xBinding( getDocumentFactory()->createInstanceWithArguments(
- CREATE_OUSTRING( "com.sun.star.table.CellValueBinding" ), aArgs ), UNO_QUERY_THROW );
- xBindable->setValueBinding( xBinding );
- }
- }
- catch( Exception& )
- {
- }
-
- // source range
- if( rClientData.maSourceRange.getLength() > 0 ) try
- {
- Reference< XListEntrySink > xEntrySink( rxCtrlModel, UNO_QUERY_THROW );
-
- // convert formula string to cell range
- FormulaParser& rParser = getFormulaParser();
- TokensFormulaContext aContext( true, false );
- aContext.setBaseAddress( CellAddress( getSheetIndex(), 0, 0 ) );
- rParser.importFormula( aContext, rClientData.maSourceRange );
- CellRangeAddress aRange;
- if( rParser.extractCellRange( aRange, aContext.getTokens(), true ) )
- {
- // create argument sequence for createInstanceWithArguments()
- NamedValue aValue;
- aValue.Name = CREATE_OUSTRING( "CellRange" );
- aValue.Value <<= aRange;
- Sequence< Any > aArgs( 1 );
- aArgs[ 0 ] <<= aValue;
-
- // create the EntrySource instance and set at the control model
- Reference< XListEntrySource > xEntrySource( getDocumentFactory()->createInstanceWithArguments(
- CREATE_OUSTRING( "com.sun.star.table.CellRangeListSource" ), aArgs ), UNO_QUERY_THROW );
- xEntrySink->setListEntrySource( xEntrySource );
- }
- }
- catch( Exception& )
- {
- }
+ // control sources
+ if( (rClientData.maLinkedCell.getLength() > 0) || (rClientData.maSourceRange.getLength() > 0) )
+ maControlConv.bindToSources( rxCtrlModel, rClientData.maLinkedCell, rClientData.maSourceRange, getSheetIndex() );
}
}
diff --git a/oox/source/xls/excelfilter.cxx b/oox/source/xls/excelfilter.cxx
index 1093b5cc7bfe..81cf12298784 100644
--- a/oox/source/xls/excelfilter.cxx
+++ b/oox/source/xls/excelfilter.cxx
@@ -27,35 +27,37 @@
************************************************************************/
#include "oox/xls/excelfilter.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include "oox/dump/biffdumper.hxx"
+#include "oox/dump/xlsbdumper.hxx"
#include "oox/helper/binaryinputstream.hxx"
#include "oox/xls/biffdetector.hxx"
#include "oox/xls/biffinputstream.hxx"
#include "oox/xls/excelchartconverter.hxx"
+#include "oox/ole/vbaproject.hxx"
#include "oox/xls/stylesbuffer.hxx"
#include "oox/xls/themebuffer.hxx"
#include "oox/xls/workbookfragment.hxx"
#include "oox/dump/biffdumper.hxx"
#include "oox/dump/xlsbdumper.hxx"
-using ::rtl::OUString;
-using ::com::sun::star::uno::Any;
-using ::com::sun::star::uno::Reference;
-using ::com::sun::star::uno::Sequence;
-using ::com::sun::star::uno::Exception;
-using ::com::sun::star::uno::UNO_QUERY;
-using ::com::sun::star::uno::XInterface;
-using ::com::sun::star::lang::XComponent;
-using ::com::sun::star::lang::XMultiServiceFactory;
-using ::com::sun::star::xml::sax::XFastDocumentHandler;
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+
using ::oox::core::BinaryFilterBase;
using ::oox::core::FragmentHandlerRef;
using ::oox::core::Relation;
using ::oox::core::Relations;
using ::oox::core::XmlFilterBase;
using ::oox::drawingml::table::TableStyleListPtr;
-
-namespace oox {
-namespace xls {
+using ::rtl::OUString;
// ============================================================================
@@ -94,8 +96,8 @@ OUString SAL_CALL ExcelFilter_getImplementationName() throw()
Sequence< OUString > SAL_CALL ExcelFilter_getSupportedServiceNames() throw()
{
- OUString aServiceName = CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilter" );
- Sequence< OUString > aSeq( &aServiceName, 1 );
+ Sequence< OUString > aSeq( 1 );
+ aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilter" );
return aSeq;
}
@@ -202,8 +204,8 @@ OUString SAL_CALL ExcelBiffFilter_getImplementationName() throw()
Sequence< OUString > SAL_CALL ExcelBiffFilter_getSupportedServiceNames() throw()
{
- OUString aServiceName = CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelBiffFilter" );
- Sequence< OUString > aSeq( &aServiceName, 1 );
+ Sequence< OUString > aSeq( 1 );
+ aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelBiffFilter" );
return aSeq;
}
@@ -269,6 +271,62 @@ OUString ExcelBiffFilter::implGetImplementationName() const
// ============================================================================
+OUString SAL_CALL ExcelVbaProjectFilter_getImplementationName() throw()
+{
+ return CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelVbaProjectFilter" );
+}
+
+Sequence< OUString > SAL_CALL ExcelVbaProjectFilter_getSupportedServiceNames() throw()
+{
+ Sequence< OUString > aSeq( 1 );
+ aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelVBAProjectFilter" );
+ return aSeq;
+}
+
+Reference< XInterface > SAL_CALL ExcelVbaProjectFilter_createInstance(
+ const Reference< XMultiServiceFactory >& rxGlobalFactory ) throw( Exception )
+{
+ return static_cast< ::cppu::OWeakObject* >( new ExcelVbaProjectFilter( rxGlobalFactory ) );
+}
+
+// ----------------------------------------------------------------------------
+
+ExcelVbaProjectFilter::ExcelVbaProjectFilter( const Reference< XMultiServiceFactory >& rxGlobalFactory ) :
+ ExcelBiffFilter( rxGlobalFactory )
+{
+}
+
+bool ExcelVbaProjectFilter::importDocument() throw()
+{
+ bool bRet = false;
+
+ // detect BIFF version and workbook stream name
+ OUString aWorkbookName;
+ BiffType eBiff = BiffDetector::detectStorageBiffVersion( aWorkbookName, getStorage() );
+ OSL_ENSURE( eBiff == BIFF8, "ExcelVbaProjectFilter::ExcelVbaProjectFilter - invalid file format" );
+ if( eBiff == BIFF8 )
+ {
+ Reference< XNameContainer > xOleNameOverrideSink;
+ getArgument( CREATE_OUSTRING( "OleNameOverrideInfo" ) ) >>= xOleNameOverrideSink;
+ WorkbookHelperRoot aHelper( *this, eBiff );
+ StorageRef xVbaPrjStrg = openSubStorage( CREATE_OUSTRING( "_VBA_PROJECT_CUR" ), false );
+ if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )
+ {
+ ole::VbaProject aVbaProject( getGlobalFactory(), Reference< com::sun::star::frame::XModel >( aHelper.getDocument(), UNO_QUERY ), CREATE_OUSTRING( "Calc" ) );
+ aVbaProject.setOleOverridesSink( xOleNameOverrideSink );
+ aVbaProject.importVbaProject( *xVbaPrjStrg, getGraphicHelper() );
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+OUString ExcelVbaProjectFilter::implGetImplementationName() const
+{
+ return ExcelVbaProjectFilter_getImplementationName();
+}
+// ============================================================================
+
} // namespace xls
} // namespace oox
diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx
index f8a49c435244..6033601fb2d2 100644
--- a/oox/source/xls/workbookhelper.cxx
+++ b/oox/source/xls/workbookhelper.cxx
@@ -72,6 +72,7 @@ using ::rtl::OUString;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::UNO_SET_THROW;