diff options
author | Daniel Rentz <dr@openoffice.org> | 2010-06-15 20:19:01 +0200 |
---|---|---|
committer | Daniel Rentz <dr@openoffice.org> | 2010-06-15 20:19:01 +0200 |
commit | 3b82bb1566db3da82e11a1a166ac458eebb4c422 (patch) | |
tree | 04d3aacfd1afb8af6fa3ff7cb1655bc55353d522 | |
parent | 5ac2cde7cad685ef5fe0e4fb4801ef15d0d5e7fc (diff) |
mib16: contributed bugfixes and various new symbols in VBA compatibility implementation
-rwxr-xr-x | sc/inc/eventuno.hxx | 91 | ||||
-rwxr-xr-x | sc/inc/sheetevents.hxx | 65 | ||||
-rwxr-xr-x | sc/source/core/data/sheetevents.cxx | 141 | ||||
-rwxr-xr-x | sc/source/filter/xml/XMLCodeNameProvider.cxx | 204 | ||||
-rwxr-xr-x | sc/source/filter/xml/XMLCodeNameProvider.hxx | 70 | ||||
-rwxr-xr-x | sc/source/ui/unoobj/eventuno.cxx | 201 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbahyperlinks.cxx | 293 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbahyperlinks.hxx | 150 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbasheetobject.cxx | 517 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbasheetobject.hxx | 220 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbasheetobjects.cxx | 534 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbasheetobjects.hxx | 113 |
12 files changed, 2599 insertions, 0 deletions
diff --git a/sc/inc/eventuno.hxx b/sc/inc/eventuno.hxx new file mode 100755 index 000000000..8f25ae487 --- /dev/null +++ b/sc/inc/eventuno.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sheetdata.hxx,v $ + * $Revision: 1.16.32.2 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_EVENTUNO_HXX +#define SC_EVENTUNO_HXX + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <cppuhelper/implbase2.hxx> +#include <svl/lstner.hxx> + +#include "global.hxx" + +class ScDocShell; + +class ScSheetEventsObj : public cppu::WeakImplHelper2< + com::sun::star::container::XNameReplace, + com::sun::star::lang::XServiceInfo>, + public SfxListener +{ +private: + ScDocShell* mpDocShell; + SCTAB mnTab; + +public: + ScSheetEventsObj(ScDocShell* pDocSh, SCTAB nT); + virtual ~ScSheetEventsObj(); + + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + + // XNameReplace + virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, + const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XNameAccess + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::uno::RuntimeException); + + // XElementAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); +}; + +#endif + diff --git a/sc/inc/sheetevents.hxx b/sc/inc/sheetevents.hxx new file mode 100755 index 000000000..a8650c078 --- /dev/null +++ b/sc/inc/sheetevents.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sheetdata.hxx,v $ + * $Revision: 1.16.32.2 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_SHEETEVENTS_HXX +#define SC_SHEETEVENTS_HXX + +#include <rtl/ustring.hxx> + +#define SC_SHEETEVENT_FOCUS 0 +#define SC_SHEETEVENT_UNFOCUS 1 +#define SC_SHEETEVENT_SELECT 2 +#define SC_SHEETEVENT_DOUBLECLICK 3 +#define SC_SHEETEVENT_RIGHTCLICK 4 +#define SC_SHEETEVENT_CHANGE 5 +#define SC_SHEETEVENT_CALCULATE 6 +#define SC_SHEETEVENT_COUNT 7 + +class ScSheetEvents +{ + rtl::OUString** mpScriptNames; + + void Clear(); + +public: + ScSheetEvents(); + ScSheetEvents(const ScSheetEvents& rOther); + ~ScSheetEvents(); + + const ScSheetEvents& operator= (const ScSheetEvents& rOther); + + const rtl::OUString* GetScript(sal_Int32 nEvent) const; + void SetScript(sal_Int32 nEvent, const rtl::OUString* pNew); + + static rtl::OUString GetEventName(sal_Int32 nEvent); +}; + +#endif + diff --git a/sc/source/core/data/sheetevents.cxx b/sc/source/core/data/sheetevents.cxx new file mode 100755 index 000000000..37546e6a3 --- /dev/null +++ b/sc/source/core/data/sheetevents.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sheetdata.cxx,v $ + * $Revision: 1.69.32.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include <tools/debug.hxx> + +#include "sheetevents.hxx" + +// ----------------------------------------------------------------------- + +// static +rtl::OUString ScSheetEvents::GetEventName(sal_Int32 nEvent) +{ + if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT) + { + DBG_ERRORFILE("invalid event number"); + return rtl::OUString(); + } + + static const sal_Char* aEventNames[] = + { + "OnFocus", // SC_SHEETEVENT_FOCUS + "OnUnfocus", // SC_SHEETEVENT_UNFOCUS + "OnSelect", // SC_SHEETEVENT_SELECT + "OnDoubleClick", // SC_SHEETEVENT_DOUBLECLICK + "OnRightClick", // SC_SHEETEVENT_RIGHTCLICK + "OnChange", // SC_SHEETEVENT_CHANGE + "OnCalculate" // SC_SHEETEVENT_CALCULATE + }; + return rtl::OUString::createFromAscii(aEventNames[nEvent]); +} + +// ----------------------------------------------------------------------- + +ScSheetEvents::ScSheetEvents() : + mpScriptNames(NULL) +{ +} + +ScSheetEvents::~ScSheetEvents() +{ + Clear(); +} + +void ScSheetEvents::Clear() +{ + if (mpScriptNames) + { + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + delete mpScriptNames[nEvent]; + delete[] mpScriptNames; + mpScriptNames = NULL; + } +} + +ScSheetEvents::ScSheetEvents(const ScSheetEvents& rOther) : + mpScriptNames(NULL) +{ + *this = rOther; +} + +const ScSheetEvents& ScSheetEvents::operator=(const ScSheetEvents& rOther) +{ + Clear(); + if (rOther.mpScriptNames) + { + mpScriptNames = new rtl::OUString*[SC_SHEETEVENT_COUNT]; + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + if (rOther.mpScriptNames[nEvent]) + mpScriptNames[nEvent] = new rtl::OUString(*rOther.mpScriptNames[nEvent]); + else + mpScriptNames[nEvent] = NULL; + } + return *this; +} + +const rtl::OUString* ScSheetEvents::GetScript(sal_Int32 nEvent) const +{ + if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT) + { + DBG_ERRORFILE("invalid event number"); + return NULL; + } + + if (mpScriptNames) + return mpScriptNames[nEvent]; + return NULL; +} + +void ScSheetEvents::SetScript(sal_Int32 nEvent, const rtl::OUString* pNew) +{ + if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT) + { + DBG_ERRORFILE("invalid event number"); + return; + } + + if (!mpScriptNames) + { + mpScriptNames = new rtl::OUString*[SC_SHEETEVENT_COUNT]; + for (sal_Int32 nEventIdx=0; nEventIdx<SC_SHEETEVENT_COUNT; ++nEventIdx) + mpScriptNames[nEventIdx] = NULL; + } + delete mpScriptNames[nEvent]; + if (pNew) + mpScriptNames[nEvent] = new rtl::OUString(*pNew); + else + mpScriptNames[nEvent] = NULL; +} + diff --git a/sc/source/filter/xml/XMLCodeNameProvider.cxx b/sc/source/filter/xml/XMLCodeNameProvider.cxx new file mode 100755 index 000000000..d65800c49 --- /dev/null +++ b/sc/source/filter/xml/XMLCodeNameProvider.cxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "XMLCodeNameProvider.hxx" +#include "document.hxx" + +using namespace rtl; +using namespace com::sun::star; + +sal_Bool XMLCodeNameProvider::_getCodeName( const uno::Any& aAny, String& rCodeName ) +{ + uno::Sequence<beans::PropertyValue> aProps; + if( !(aAny >>= aProps) ) + return sal_False; + + OUString sCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") ); + sal_Int32 nPropCount = aProps.getLength(); + for( sal_Int32 i=0; i<nPropCount; i++ ) + { + if( aProps[i].Name == sCodeNameProp ) + { + OUString sCodeName; + if( aProps[i].Value >>= sCodeName ) + { + rCodeName = sCodeName; + return sal_True; + } + } + } + + return sal_False; +} + + +XMLCodeNameProvider::XMLCodeNameProvider( ScDocument* pDoc ) : + mpDoc( pDoc ), + msDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") ), + msCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) +{ +} + +XMLCodeNameProvider::~XMLCodeNameProvider() +{ +} + +::sal_Bool SAL_CALL XMLCodeNameProvider::hasByName( const OUString& aName ) + throw (uno::RuntimeException ) +{ + if( aName == msDocName ) + return mpDoc->GetCodeName().Len() > 0; + + SCTAB nCount = mpDoc->GetTableCount(); + String sName( aName ); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName ) + { + mpDoc->GetCodeName( i, sCodeName ); + return sCodeName.Len() > 0; + } + } + + return sal_False; +} + +uno::Any SAL_CALL XMLCodeNameProvider::getByName( const OUString& aName ) + throw (container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + uno::Any aRet; + uno::Sequence<beans::PropertyValue> aProps(1); + aProps[0].Name = msCodeNameProp; + if( aName == msDocName ) + { + OUString sUCodeName( mpDoc->GetCodeName() ); + aProps[0].Value <<= sUCodeName; + aRet <<= aProps; + return aRet; + } + + SCTAB nCount = mpDoc->GetTableCount(); + String sName( aName ); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName ) + { + mpDoc->GetCodeName( i, sCodeName ); + OUString sUCodeName( sCodeName ); + aProps[0].Value <<= sUCodeName; + aRet <<= aProps; + return aRet; + } + } + + return aRet; +} + +uno::Sequence< OUString > SAL_CALL XMLCodeNameProvider::getElementNames( ) + throw (uno::RuntimeException) +{ + SCTAB nCount = mpDoc->GetTableCount() + 1; + uno::Sequence< rtl::OUString > aNames( nCount ); + sal_Int32 nRealCount = 0; + + if( mpDoc->GetCodeName().Len() ) + aNames[nRealCount++] = msDocName; + + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + mpDoc->GetCodeName( i, sCodeName ); + if( sCodeName.Len() > 0 ) + { + if( mpDoc->GetName( i, sSheetName ) ) + aNames[nRealCount++] = sSheetName; + } + } + + if( nCount != nRealCount ) + aNames.realloc( nRealCount ); + + return aNames; +} + +uno::Type SAL_CALL XMLCodeNameProvider::getElementType( ) + throw (uno::RuntimeException) +{ + return uno::Type(); +} + +::sal_Bool SAL_CALL XMLCodeNameProvider::hasElements() + throw (uno::RuntimeException ) +{ + if( mpDoc->GetCodeName().Len() > 0 ) + return sal_True; + + SCTAB nCount = mpDoc->GetTableCount(); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + mpDoc->GetCodeName( i, sCodeName ); + if( sCodeName.Len() > 0 && mpDoc->GetName( i, sSheetName ) ) + return sal_True; + } + + return sal_False; +} + +void XMLCodeNameProvider::set( const uno::Reference< container::XNameAccess>& xNameAccess, ScDocument *pDoc ) +{ + uno::Any aAny; + OUString sDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") ); + String sCodeName; + if( xNameAccess->hasByName( sDocName ) ) + { + aAny = xNameAccess->getByName( sDocName ); + if( _getCodeName( aAny, sCodeName ) ) + pDoc->SetCodeName( sCodeName ); + } + + SCTAB nCount = pDoc->GetTableCount(); + String sSheetName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( pDoc->GetName( i, sSheetName ) && + xNameAccess->hasByName( sSheetName ) ) + { + aAny = xNameAccess->getByName( sSheetName ); + if( _getCodeName( aAny, sCodeName ) ) + pDoc->SetCodeName( i, sCodeName ); + } + } +} diff --git a/sc/source/filter/xml/XMLCodeNameProvider.hxx b/sc/source/filter/xml/XMLCodeNameProvider.hxx new file mode 100755 index 000000000..b90acddd6 --- /dev/null +++ b/sc/source/filter/xml/XMLCodeNameProvider.hxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCODENAMEPROVIDER_HXX +#define SC_XMLCODENAMEPROVIDER_HXX + +#include <com/sun/star/container/XNameAccess.hpp> +#include <cppuhelper/implbase1.hxx> + +class ScDocument; +class String; + +class XMLCodeNameProvider : public ::cppu::WeakImplHelper1< ::com::sun::star::container::XNameAccess > +{ + ScDocument* mpDoc; + ::rtl::OUString msDocName; + ::rtl::OUString msCodeNameProp; + + static sal_Bool _getCodeName( const ::com::sun::star::uno::Any& aAny, + String& rCodeName ); + +public: + XMLCodeNameProvider( ScDocument* pDoc ); + virtual ~XMLCodeNameProvider(); + + virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL hasElements() + throw (::com::sun::star::uno::RuntimeException ); + + static void set( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& xNameAccess, ScDocument *pDoc ); +}; + +#endif diff --git a/sc/source/ui/unoobj/eventuno.cxx b/sc/source/ui/unoobj/eventuno.cxx new file mode 100755 index 000000000..d7de00f4c --- /dev/null +++ b/sc/source/ui/unoobj/eventuno.cxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tokenuno.cxx,v $ + * $Revision: 1.6.108.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include "eventuno.hxx" +#include "miscuno.hxx" +#include "unoguard.hxx" +#include "docsh.hxx" +#include "sheetevents.hxx" +#include "unonames.hxx" + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------ + +SC_SIMPLE_SERVICE_INFO( ScSheetEventsObj, "ScSheetEventsObj", "com.sun.star.document.Events" ) + +//------------------------------------------------------------------------ + +ScSheetEventsObj::ScSheetEventsObj(ScDocShell* pDocSh, SCTAB nT) : + mpDocShell( pDocSh ), + mnTab( nT ) +{ + mpDocShell->GetDocument()->AddUnoObject(*this); +} + +ScSheetEventsObj::~ScSheetEventsObj() +{ + if (mpDocShell) + mpDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScSheetEventsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + //! reference update + if ( rHint.ISA( SfxSimpleHint ) && + ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + { + mpDocShell = NULL; + } +} + +sal_Int32 lcl_GetEventFromName( const rtl::OUString& aName ) +{ + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + if ( aName == ScSheetEvents::GetEventName(nEvent) ) + return nEvent; + + return -1; // not found +} + +// XNameReplace + +void SAL_CALL ScSheetEventsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement ) + throw(lang::IllegalArgumentException, container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (!mpDocShell) + throw uno::RuntimeException(); + + sal_Int32 nEvent = lcl_GetEventFromName(aName); + if (nEvent < 0) + throw container::NoSuchElementException(); + + ScSheetEvents aNewEvents; + const ScSheetEvents* pOldEvents = mpDocShell->GetDocument()->GetSheetEvents(mnTab); + if (pOldEvents) + aNewEvents = *pOldEvents; + + rtl::OUString aScript; + if ( aElement.hasValue() ) // empty Any -> reset event + { + uno::Sequence<beans::PropertyValue> aPropSeq; + if ( aElement >>= aPropSeq ) + { + sal_Int32 nPropCount = aPropSeq.getLength(); + for (sal_Int32 nPos=0; nPos<nPropCount; ++nPos) + { + const beans::PropertyValue& rProp = aPropSeq[nPos]; + if ( rProp.Name.compareToAscii( SC_UNO_EVENTTYPE ) == 0 ) + { + rtl::OUString aEventType; + if ( rProp.Value >>= aEventType ) + { + // only "Script" is supported + if ( aEventType.compareToAscii( SC_UNO_SCRIPT ) != 0 ) + throw lang::IllegalArgumentException(); + } + } + else if ( rProp.Name.compareToAscii( SC_UNO_SCRIPT ) == 0 ) + rProp.Value >>= aScript; + } + } + } + if (aScript.getLength()) + aNewEvents.SetScript( nEvent, &aScript ); + else + aNewEvents.SetScript( nEvent, NULL ); // reset + + mpDocShell->GetDocument()->SetSheetEvents( mnTab, &aNewEvents ); + mpDocShell->SetDocumentModified(); +} + +// XNameAccess + +uno::Any SAL_CALL ScSheetEventsObj::getByName( const rtl::OUString& aName ) + throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nEvent = lcl_GetEventFromName(aName); + if (nEvent < 0) + throw container::NoSuchElementException(); + + const rtl::OUString* pScript = NULL; + if (mpDocShell) + { + const ScSheetEvents* pEvents = mpDocShell->GetDocument()->GetSheetEvents(mnTab); + if (pEvents) + pScript = pEvents->GetScript(nEvent); + } + + uno::Any aRet; + if (pScript) + { + uno::Sequence<beans::PropertyValue> aPropSeq( 2 ); + aPropSeq[0] = beans::PropertyValue( + rtl::OUString::createFromAscii("EventType"), -1, + uno::makeAny( rtl::OUString::createFromAscii("Script") ), beans::PropertyState_DIRECT_VALUE ); + aPropSeq[1] = beans::PropertyValue( + rtl::OUString::createFromAscii("Script"), -1, + uno::makeAny( *pScript ), beans::PropertyState_DIRECT_VALUE ); + aRet <<= aPropSeq; + } + // empty Any if nothing was set + return aRet; +} + +uno::Sequence<rtl::OUString> SAL_CALL ScSheetEventsObj::getElementNames() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Sequence<rtl::OUString> aNames(SC_SHEETEVENT_COUNT); + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + aNames[nEvent] = ScSheetEvents::GetEventName(nEvent); + return aNames; +} + +sal_Bool SAL_CALL ScSheetEventsObj::hasByName( const ::rtl::OUString& aName ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nEvent = lcl_GetEventFromName(aName); + return (nEvent >= 0); +} + +// XElementAccess + +uno::Type SAL_CALL ScSheetEventsObj::getElementType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return getCppuType((uno::Sequence<beans::PropertyValue>*)0); +} + +sal_Bool SAL_CALL ScSheetEventsObj::hasElements() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (mpDocShell) + return sal_True; + return sal_False; +} + + + diff --git a/sc/source/ui/vba/vbahyperlinks.cxx b/sc/source/ui/vba/vbahyperlinks.cxx new file mode 100755 index 000000000..529b9a273 --- /dev/null +++ b/sc/source/ui/vba/vbahyperlinks.cxx @@ -0,0 +1,293 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbahyperlinks.hxx" +#include <algorithm> +#include <vector> +#include <ooo/vba/office/MsoHyperlinkType.hpp> +#include "rangelst.hxx" +#include "vbahyperlink.hxx" +#include "vbarange.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; +using ::rtl::OUString; + +// ============================================================================ + +namespace { + +/** Returns true, if every range of rxInner is contained in any range of rScOuter. */ +bool lclContains( const ScRangeList& rScOuter, const uno::Reference< excel::XRange >& rxInner ) throw (uno::RuntimeException) +{ + const ScRangeList& rScInner = ScVbaRange::getScRangeList( rxInner ); + if( (rScInner.Count() == 0) || (rScOuter.Count() == 0) ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Empty range objects" ) ), uno::Reference< uno::XInterface >() ); + + for( ULONG nIndex = 0, nCount = rScInner.Count(); nIndex < nCount; ++nIndex ) + if( !rScOuter.In( *rScInner.GetObject( nIndex ) ) ) + return false; + return true; +} + +// ---------------------------------------------------------------------------- + +/** Functor to decide whether the anchors of two Hyperlink objects are equal. */ +struct EqualAnchorFunctor +{ + uno::Reference< excel::XRange > mxAnchorRange; + uno::Reference< msforms::XShape > mxAnchorShape; + sal_Int32 mnType; + EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException); + bool operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException); +}; + +EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException) : + mnType( rxHlink->getType() ) +{ + switch( mnType ) + { + case office::MsoHyperlinkType::msoHyperlinkRange: + mxAnchorRange.set( rxHlink->getRange(), uno::UNO_QUERY_THROW ); + break; + case office::MsoHyperlinkType::msoHyperlinkShape: + case office::MsoHyperlinkType::msoHyperlinkInlineShape: + mxAnchorShape.set( rxHlink->getShape(), uno::UNO_QUERY_THROW ); + break; + default: + throw uno::RuntimeException(); + } +} + +bool EqualAnchorFunctor::operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException) +{ + sal_Int32 nType = rxHlink->getType(); + if( nType != mnType ) + return false; + + switch( nType ) + { + case office::MsoHyperlinkType::msoHyperlinkRange: + { + uno::Reference< excel::XRange > xAnchorRange( rxHlink->getRange(), uno::UNO_QUERY_THROW ); + const ScRangeList& rScRanges1 = ScVbaRange::getScRangeList( xAnchorRange ); + const ScRangeList& rScRanges2 = ScVbaRange::getScRangeList( mxAnchorRange ); + return (rScRanges1.Count() == 1) && (rScRanges2.Count() == 1) && (*rScRanges1.GetObject( 0 ) == *rScRanges2.GetObject( 0 )); + } + case office::MsoHyperlinkType::msoHyperlinkShape: + case office::MsoHyperlinkType::msoHyperlinkInlineShape: + { + uno::Reference< msforms::XShape > xAnchorShape( rxHlink->getShape(), uno::UNO_QUERY_THROW ); + return xAnchorShape.get() == mxAnchorShape.get(); + } + default: + throw uno::RuntimeException(); + } +} + +} // namespace + +// ============================================================================ + +namespace detail { + +class ScVbaHlinkContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess > +{ +public: + explicit ScVbaHlinkContainer() throw (uno::RuntimeException); + explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, const ScRangeList& rScRanges ) throw (uno::RuntimeException); + virtual ~ScVbaHlinkContainer(); + + /** Inserts the passed hyperlink into the collection. Will remove a + Hyperlink object with the same anchor as the passed Hyperlink object. */ + void insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException); + virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); + + // XElementAccess + virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException); + +private: + typedef ::std::vector< uno::Reference< excel::XHyperlink > > HyperlinkVector; + HyperlinkVector maHlinks; +}; + +// ---------------------------------------------------------------------------- + +ScVbaHlinkContainer::ScVbaHlinkContainer() throw (uno::RuntimeException) +{ + // TODO FIXME: fill with existing hyperlinks +} + +ScVbaHlinkContainer::ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, + const ScRangeList& rScRanges ) throw (uno::RuntimeException) +{ + for( sal_Int32 nIndex = 0, nCount = rxSheetContainer->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< excel::XHyperlink > xHlink( rxSheetContainer->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XRange > xHlinkRange( xHlink->getRange(), uno::UNO_QUERY_THROW ); + if( lclContains( rScRanges, xHlinkRange ) ) + maHlinks.push_back( xHlink ); + } +} + +ScVbaHlinkContainer::~ScVbaHlinkContainer() +{ +} + +void ScVbaHlinkContainer::insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException) +{ + HyperlinkVector::iterator aIt = ::std::find_if( maHlinks.begin(), maHlinks.end(), EqualAnchorFunctor( rxHlink ) ); + if( aIt == maHlinks.end() ) + maHlinks.push_back( rxHlink ); + else + *aIt = rxHlink; +} + +sal_Int32 SAL_CALL ScVbaHlinkContainer::getCount() throw (uno::RuntimeException) +{ + return static_cast< sal_Int32 >( maHlinks.size() ); +} + +uno::Any SAL_CALL ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) +{ + if( (0 <= nIndex) && (nIndex < getCount()) ) + return uno::Any( maHlinks[ static_cast< size_t >( nIndex ) ] ); + throw lang::IndexOutOfBoundsException(); +} + +uno::Type SAL_CALL ScVbaHlinkContainer::getElementType() throw (uno::RuntimeException) +{ + return excel::XHyperlink::static_type( 0 ); +} + +sal_Bool SAL_CALL ScVbaHlinkContainer::hasElements() throw (uno::RuntimeException) +{ + return !maHlinks.empty(); +} + +// ============================================================================ + +ScVbaHlinkContainerMember::ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ) : + mxContainer( pContainer ) +{ +} + +ScVbaHlinkContainerMember::~ScVbaHlinkContainerMember() +{ +} + +} // namespace detail + +// ============================================================================ + +ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext ) throw (uno::RuntimeException) : + detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer ), + ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) ) +{ +} + +ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (uno::RuntimeException) : + detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer( rxSheetHlinks->mxContainer, rScRanges ) ), + ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) ), + mxSheetHlinks( rxSheetHlinks ) +{ +} + +ScVbaHyperlinks::~ScVbaHyperlinks() +{ +} + +// XHyperlinks ---------------------------------------------------------------- + +uno::Reference< excel::XHyperlink > SAL_CALL ScVbaHyperlinks::Add( + const uno::Any& rAnchor, const uno::Any& rAddress, const uno::Any& rSubAddress, + const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException) +{ + /* If this Hyperlinks object has been craeted from a Range object, the + call to Add() is passed to the Hyperlinks object of the parent + worksheet. This container will not be modified (it will not contain the + inserted hyperlink). + For details, see documentation in hyperlinks.hxx. + */ + if( mxSheetHlinks.is() ) + return mxSheetHlinks->Add( rAnchor, rAddress, rSubAddress, rScreenTip, rTextToDisplay ); + + // get anchor object (can be a Range or a Shape object) + uno::Reference< XHelperInterface > xAnchor( rAnchor, uno::UNO_QUERY_THROW ); + + /* Create the Hyperlink object, this tries to insert the hyperlink into + the spreadsheet document. Parent of the Hyperlink is the anchor object. */ + uno::Reference< excel::XHyperlink > xHlink( new ScVbaHyperlink( + xAnchor, mxContext, rAddress, rSubAddress, rScreenTip, rTextToDisplay ) ); + + /* If creation of the hyperlink did not throw, insert it into the + collection. */ + mxContainer->insertHyperlink( xHlink ); + return xHlink; +} + +void SAL_CALL ScVbaHyperlinks::Delete() throw (uno::RuntimeException) +{ + // FIXME not implemented + throw uno::RuntimeException(); +} + +// XEnumerationAccess --------------------------------------------------------- + +uno::Reference< container::XEnumeration > SAL_CALL ScVbaHyperlinks::createEnumeration() throw (uno::RuntimeException) +{ + return new SimpleIndexAccessToEnumeration( m_xIndexAccess ); +} + +// XElementAccess ------------------------------------------------------------- + +uno::Type SAL_CALL ScVbaHyperlinks::getElementType() throw (uno::RuntimeException) +{ + return excel::XHyperlink::static_type( 0 ); +} + +// ScVbaCollectionBase -------------------------------------------------------- + +uno::Any ScVbaHyperlinks::createCollectionObject( const uno::Any& rSource ) +{ + // container stores XHyperlink objects, just return the passed object + return rSource; +} + +// XHelperInterface ----------------------------------------------------------- + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks, "ooo.vba.excel.Hyperlinks" ) + +// ============================================================================ diff --git a/sc/source/ui/vba/vbahyperlinks.hxx b/sc/source/ui/vba/vbahyperlinks.hxx new file mode 100755 index 000000000..8ce015101 --- /dev/null +++ b/sc/source/ui/vba/vbahyperlinks.hxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_HYPERLINKS_HXX +#define SC_VBA_HYPERLINKS_HXX + +#include <ooo/vba/excel/XHyperlinks.hpp> +#include <rtl/ref.hxx> +#include <vbahelper/vbacollectionimpl.hxx> + +class ScRangeList; + +// ============================================================================ + +namespace detail { + +class ScVbaHlinkContainer; +typedef ::rtl::Reference< ScVbaHlinkContainer > ScVbaHlinkContainerRef; + +/** Base class for ScVbaHyperlinks to get an initialized ScVbaHlinkContainer + class member before the ScVbaHyperlinks_BASE base class will be constructed. + */ +struct ScVbaHlinkContainerMember +{ + ScVbaHlinkContainerRef mxContainer; + + explicit ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ); + ~ScVbaHlinkContainerMember(); +}; + +} // namespace detail + +// ============================================================================ + +class ScVbaHyperlinks; +typedef ::rtl::Reference< ScVbaHyperlinks > ScVbaHyperlinksRef; + +typedef CollTestImplHelper< ov::excel::XHyperlinks > ScVbaHyperlinks_BASE; + +/** Represents a collection of hyperlinks of a worksheet or of a range. + + When a Hyperlinks collection object has been constructed from a VBA + Worksheet object, it will always represent the current set of all + hyperlinks existing in the sheet. Insertion and deletion of hyperlinks will + be reflected by the instance. + + When a Hyperlinks collection object has been constructed from a VBA Range + object, it will represent the set of hyperlinks that have existed at its + construction time, and that are located completely inside the range(s) + represented by the Range object. Insertion and deletion of hyperlinks will + *not* be reflected by that instance. The instance will always offer all + hyperlinks it has been constructed with, even if they no longer exist. + Furthermore, the instance will not offer hyperlinks inserted later, even if + the instance itself has been used to insert the new hyperlinks. + + VBA code example: + + With ThisWorkbook.Worksheets(1) + + Set hlinks = .Hyperlinks ' global Hyperlinks object + Set myrange = .Range("A1:C3") + Set rangelinks1 = myrange.Hyperlinks ' hyperlinks of range A1:C3 + + MsgBox hlinks.Count ' 0 + MsgBox rangelinks1.Count ' 0 + + hlinks.Add .Range("A1"), "http://example.com" + ' a new hyperlink has been added in cell A1 + + MsgBox hlinks.Count ' 1 + MsgBox rangelinks1.Count ' still 0! + Set rangelinks2 = myrange.Hyperlinks ' hyperlinks of range A1:C3 + MsgBox rangelinks2.Count ' 1 (constructed after Add) + + rangelinks1.Add .Range("A2"), "http://example.com" + ' a new hyperlink has been constructed via the rangelinks1 object + ' but this addition has been done by the worksheet Hyperlinks object + + MsgBox hlinks.Count ' 2 + MsgBox rangelinks1.Count ' still 0!!! + MsgBox rangelinks2.Count ' still 1!!! + MsgBox myrange.Hyperlinks.Count ' 2 (constructed after Add) + + End With + */ +class ScVbaHyperlinks : private detail::ScVbaHlinkContainerMember, public ScVbaHyperlinks_BASE +{ +public: + explicit ScVbaHyperlinks( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ) throw (css::uno::RuntimeException); + + explicit ScVbaHyperlinks( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (css::uno::RuntimeException); + + virtual ~ScVbaHyperlinks(); + + // XHyperlinks + virtual css::uno::Reference< ov::excel::XHyperlink > SAL_CALL Add( + const css::uno::Any& rAnchor, const css::uno::Any& rAddress, const css::uno::Any& rSubAddress, + const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay ) + throw (css::uno::RuntimeException); + + virtual void SAL_CALL Delete() throw (css::uno::RuntimeException); + + // XEnumerationAccess + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException); + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); + + // ScVbaCollectionBase + virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +private: + ScVbaHyperlinksRef mxSheetHlinks; +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbasheetobject.cxx b/sc/source/ui/vba/vbasheetobject.cxx new file mode 100755 index 000000000..215a62cec --- /dev/null +++ b/sc/source/ui/vba/vbasheetobject.cxx @@ -0,0 +1,517 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbasheetobject.hxx" +#include <com/sun/star/awt/TextAlign.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <com/sun/star/script/XEventAttacherManager.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <ooo/vba/excel/Constants.hpp> +#include <ooo/vba/excel/XlOrientation.hpp> +#include <ooo/vba/excel/XlPlacement.hpp> +#include <rtl/ustrbuf.hxx> +#include <filter/msfilter/msvbahelper.hxx> +#include <oox/helper/helper.hxx> +#include "vbafont.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +// ============================================================================ + +ScVbaButtonCharacters::ScVbaButtonCharacters( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< beans::XPropertySet >& rxPropSet, + const ScVbaPalette& rPalette, + const uno::Any& rStart, + const uno::Any& rLength ) throw (uno::RuntimeException) : + ScVbaButtonCharacters_BASE( rxParent, rxContext ), + maPalette( rPalette ), + mxPropSet( rxPropSet, uno::UNO_SET_THROW ) +{ + // extract optional start parameter (missing or invalid -> from beginning) + if( !(rStart >>= mnStart) || (mnStart < 1) ) + mnStart = 1; + --mnStart; // VBA is 1-based, rtl string is 0-based + + // extract optional length parameter (missing or invalid -> to end) + if( !(rLength >>= mnLength) || (mnLength < 1) ) + mnLength = SAL_MAX_INT32; +} + +ScVbaButtonCharacters::~ScVbaButtonCharacters() +{ +} + +// XCharacters attributes + +OUString SAL_CALL ScVbaButtonCharacters::getCaption() throw (uno::RuntimeException) +{ + // ignore invalid mnStart and/or mnLength members + OUString aString = getFullString(); + sal_Int32 nStart = ::std::min( mnStart, aString.getLength() ); + sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart ); + return aString.copy( nStart, nLength ); +} + +void SAL_CALL ScVbaButtonCharacters::setCaption( const OUString& rCaption ) throw (uno::RuntimeException) +{ + /* Replace the covered text with the passed text, ignore invalid mnStart + and/or mnLength members. This operation does not affect the mnLength + parameter. If the inserted text is longer than mnLength, the additional + characters are not covered by this object. If the inserted text is + shorter than mnLength, other uncovered characters from the original + string will be covered now, thus may be changed with subsequent + operations. */ + OUString aString = getFullString(); + sal_Int32 nStart = ::std::min( mnStart, aString.getLength() ); + sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart ); + setFullString( aString.replaceAt( nStart, nLength, rCaption ) ); +} + +sal_Int32 SAL_CALL ScVbaButtonCharacters::getCount() throw (uno::RuntimeException) +{ + // always return the total length of the caption + return getFullString().getLength(); +} + +OUString SAL_CALL ScVbaButtonCharacters::getText() throw (uno::RuntimeException) +{ + // Text attribute same as Caption attribute? + return getCaption(); +} + +void SAL_CALL ScVbaButtonCharacters::setText( const OUString& rText ) throw (uno::RuntimeException) +{ + // Text attribute same as Caption attribute? + setCaption( rText ); +} + +uno::Reference< excel::XFont > SAL_CALL ScVbaButtonCharacters::getFont() throw (uno::RuntimeException) +{ + return new ScVbaFont( this, mxContext, maPalette, mxPropSet, 0, true ); +} + +void SAL_CALL ScVbaButtonCharacters::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +// XCharacters methods + +void SAL_CALL ScVbaButtonCharacters::Insert( const OUString& rString ) throw (uno::RuntimeException) +{ + /* The Insert() operation is in fact "replace covered characters", at + least for buttons... It seems there is no easy way to really insert a + substring. This operation does not affect the mnLength parameter. */ + setCaption( rString ); +} + +void SAL_CALL ScVbaButtonCharacters::Delete() throw (uno::RuntimeException) +{ + /* The Delete() operation is nothing else than "replace with empty string". + This does not affect the mnLength parameter, multiple calls of Delete() + will remove characters as long as there are some more covered by this + object. */ + setCaption( OUString() ); +} + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtonCharacters, "ooo.vba.excel.Characters" ) + +// private + +OUString ScVbaButtonCharacters::getFullString() const throw (uno::RuntimeException) +{ + return mxPropSet->getPropertyValue( CREATE_OUSTRING( "Label" ) ).get< OUString >(); +} + +void ScVbaButtonCharacters::setFullString( const OUString& rString ) throw (uno::RuntimeException) +{ + mxPropSet->setPropertyValue( CREATE_OUSTRING( "Label" ), uno::Any( rString ) ); +} + +// ============================================================================ + +ScVbaSheetObjectBase::ScVbaSheetObjectBase( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) : + ScVbaSheetObject_BASE( rxParent, rxContext ), + maPalette( rxModel ), + mxModel( rxModel, uno::UNO_SET_THROW ), + mxShape( rxShape, uno::UNO_SET_THROW ), + mxShapeProps( rxShape, uno::UNO_QUERY_THROW ) +{ +} + +// XSheetObject attributes + +double SAL_CALL ScVbaSheetObjectBase::getLeft() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getPosition().X ); +} + +void SAL_CALL ScVbaSheetObjectBase::setLeft( double fLeft ) throw (uno::RuntimeException) +{ + if( fLeft < 0.0 ) + throw uno::RuntimeException(); + mxShape->setPosition( awt::Point( PointsToHmm( fLeft ), mxShape->getPosition().Y ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getTop() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getPosition().Y ); +} + +void SAL_CALL ScVbaSheetObjectBase::setTop( double fTop ) throw (uno::RuntimeException) +{ + if( fTop < 0.0 ) + throw uno::RuntimeException(); + mxShape->setPosition( awt::Point( mxShape->getPosition().X, PointsToHmm( fTop ) ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getWidth() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getSize().Width ); +} + +void SAL_CALL ScVbaSheetObjectBase::setWidth( double fWidth ) throw (uno::RuntimeException) +{ + if( fWidth <= 0.0 ) + throw uno::RuntimeException(); + mxShape->setSize( awt::Size( PointsToHmm( fWidth ), mxShape->getSize().Height ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getHeight() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getSize().Height ); +} + +void SAL_CALL ScVbaSheetObjectBase::setHeight( double fHeight ) throw (uno::RuntimeException) +{ + if( fHeight <= 0.0 ) + throw uno::RuntimeException(); + mxShape->setSize( awt::Size( mxShape->getSize().Width, PointsToHmm( fHeight ) ) ); +} + +OUString SAL_CALL ScVbaSheetObjectBase::getName() throw (uno::RuntimeException) +{ + return mxShapeProps->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaSheetObjectBase::setName( const OUString& rName ) throw (uno::RuntimeException) +{ + mxShapeProps->setPropertyValue( CREATE_OUSTRING( "Name" ), uno::Any( rName ) ); +} + +sal_Int32 SAL_CALL ScVbaSheetObjectBase::getPlacement() throw (uno::RuntimeException) +{ + // TODO + return excel::XlPlacement::xlMoveAndSize; +} + +void SAL_CALL ScVbaSheetObjectBase::setPlacement( sal_Int32 /*nPlacement*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +sal_Bool SAL_CALL ScVbaSheetObjectBase::getPrintObject() throw (uno::RuntimeException) +{ + // not supported + return sal_True; +} + +void SAL_CALL ScVbaSheetObjectBase::setPrintObject( sal_Bool /*bPrintObject*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// private + +void ScVbaSheetObjectBase::setDefaultProperties( sal_Int32 nIndex ) throw (uno::RuntimeException) +{ + OUString aName = ::rtl::OUStringBuffer( implGetBaseName() ).append( sal_Unicode( ' ' ) ).append( nIndex + 1 ).makeStringAndClear(); + setName( aName ); + implSetDefaultProperties(); +} + +void ScVbaSheetObjectBase::implSetDefaultProperties() throw (uno::RuntimeException) +{ +} + +// ============================================================================ + +ScVbaControlObjectBase::ScVbaControlObjectBase( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< container::XIndexContainer >& rxFormIC, + const uno::Reference< drawing::XControlShape >& rxControlShape, + ListenerType eListenerType ) throw (uno::RuntimeException) : + ScVbaControlObject_BASE( rxParent, rxContext, rxModel, uno::Reference< drawing::XShape >( rxControlShape, uno::UNO_QUERY_THROW ) ), + mxFormIC( rxFormIC, uno::UNO_SET_THROW ), + mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ) +{ + // set listener and event name to be used for OnAction attribute + switch( eListenerType ) + { + case LISTENER_ACTION: + maListenerType = CREATE_OUSTRING( "XActionListener" ); + maEventMethod = CREATE_OUSTRING( "actionPerformed" ); + break; + case LISTENER_MOUSE: + maListenerType = CREATE_OUSTRING( "XMouseListener" ); + maEventMethod = CREATE_OUSTRING( "mouseReleased" ); + break; + case LISTENER_TEXT: + maListenerType = CREATE_OUSTRING( "XTextListener" ); + maEventMethod = CREATE_OUSTRING( "textChanged" ); + break; + case LISTENER_VALUE: + maListenerType = CREATE_OUSTRING( "XAdjustmentListener" ); + maEventMethod = CREATE_OUSTRING( "adjustmentValueChanged" ); + break; + case LISTENER_CHANGE: + maListenerType = CREATE_OUSTRING( "XChangeListener" ); + maEventMethod = CREATE_OUSTRING( "changed" ); + break; + // no default, to let the compiler complain about missing case + } +} + +// XSheetObject attributes + +OUString SAL_CALL ScVbaControlObjectBase::getName() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaControlObjectBase::setName( const OUString& rName ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Name" ), uno::Any( rName ) ); +} + +OUString SAL_CALL ScVbaControlObjectBase::getOnAction() throw (uno::RuntimeException) +{ + uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW ); + sal_Int32 nIndex = getModelIndexInForm(); + uno::Sequence< script::ScriptEventDescriptor > aEvents = xEventMgr->getScriptEvents( nIndex ); + if( aEvents.hasElements() ) + { + const script::ScriptEventDescriptor* pEvent = aEvents.getConstArray(); + const script::ScriptEventDescriptor* pEventEnd = pEvent + aEvents.getLength(); + const OUString aScriptType = CREATE_OUSTRING( "Script" ); + for( ; pEvent < pEventEnd; ++pEvent ) + if( (pEvent->ListenerType == maListenerType) && (pEvent->EventMethod == maEventMethod) && (pEvent->ScriptType == aScriptType) ) + return extractMacroName( pEvent->ScriptCode ); + } + return OUString(); +} + +void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName ) throw (uno::RuntimeException) +{ + uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW ); + sal_Int32 nIndex = getModelIndexInForm(); + + // first, remove a registered event (try/catch just in case implementation throws) + try { xEventMgr->revokeScriptEvent( nIndex, maListenerType, maEventMethod, OUString() ); } catch( uno::Exception& ) {} + + // if a macro name has been passed, try to attach it to the event + if( rMacroName.getLength() > 0 ) + { + VBAMacroResolvedInfo aResolvedMacro = resolveVBAMacro( getSfxObjShell( mxModel ), rMacroName ); + if( !aResolvedMacro.IsResolved() ) + throw uno::RuntimeException(); + script::ScriptEventDescriptor aDescriptor; + aDescriptor.ListenerType = maListenerType; + aDescriptor.EventMethod = maEventMethod; + aDescriptor.ScriptType = CREATE_OUSTRING( "Script" ); + aDescriptor.ScriptCode = makeMacroURL( aResolvedMacro.ResolvedMacro() ); + xEventMgr->registerScriptEvent( nIndex, aDescriptor ); + } +} + +sal_Bool SAL_CALL ScVbaControlObjectBase::getPrintObject() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Printable" ) ).get< sal_Bool >(); +} + +void SAL_CALL ScVbaControlObjectBase::setPrintObject( sal_Bool bPrintObject ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Printable" ), uno::Any( bPrintObject ) ); +} + +// XControlObject attributes + +sal_Bool SAL_CALL ScVbaControlObjectBase::getAutoSize() throw (uno::RuntimeException) +{ + // not supported + return sal_False; +} + +void SAL_CALL ScVbaControlObjectBase::setAutoSize( sal_Bool /*bAutoSize*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// private + +sal_Int32 ScVbaControlObjectBase::getModelIndexInForm() const throw (uno::RuntimeException) +{ + for( sal_Int32 nIndex = 0, nCount = mxFormIC->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< beans::XPropertySet > xProps( mxFormIC->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + if( mxControlProps.get() == xProps.get() ) + return nIndex; + } + throw uno::RuntimeException(); +} + +// ============================================================================ + +ScVbaButton::ScVbaButton( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< container::XIndexContainer >& rxFormIC, + const uno::Reference< drawing::XControlShape >& rxControlShape ) throw (uno::RuntimeException) : + ScVbaButton_BASE( rxParent, rxContext, rxModel, rxFormIC, rxControlShape, LISTENER_ACTION ) +{ +} + +// XButton attributes + +OUString SAL_CALL ScVbaButton::getCaption() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Label" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaButton::setCaption( const OUString& rCaption ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Label" ), uno::Any( rCaption ) ); +} + +uno::Reference< excel::XFont > SAL_CALL ScVbaButton::getFont() throw (uno::RuntimeException) +{ + return new ScVbaFont( this, mxContext, maPalette, mxControlProps, 0, true ); +} + +void SAL_CALL ScVbaButton::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +sal_Int32 SAL_CALL ScVbaButton::getHorizontalAlignment() throw (uno::RuntimeException) +{ + switch( mxControlProps->getPropertyValue( CREATE_OUSTRING( "Align" ) ).get< sal_Int16 >() ) + { + case awt::TextAlign::LEFT: return excel::Constants::xlLeft; + case awt::TextAlign::RIGHT: return excel::Constants::xlRight; + case awt::TextAlign::CENTER: return excel::Constants::xlCenter; + } + return excel::Constants::xlCenter; +} + +void SAL_CALL ScVbaButton::setHorizontalAlignment( sal_Int32 nAlign ) throw (uno::RuntimeException) +{ + sal_Int32 nAwtAlign = awt::TextAlign::CENTER; + switch( nAlign ) + { + case excel::Constants::xlLeft: nAwtAlign = awt::TextAlign::LEFT; break; + case excel::Constants::xlRight: nAwtAlign = awt::TextAlign::RIGHT; break; + case excel::Constants::xlCenter: nAwtAlign = awt::TextAlign::CENTER; break; + } + // form controls expect short value + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Align" ), uno::Any( static_cast< sal_Int16 >( nAwtAlign ) ) ); +} + +sal_Int32 SAL_CALL ScVbaButton::getVerticalAlignment() throw (uno::RuntimeException) +{ + switch( mxControlProps->getPropertyValue( CREATE_OUSTRING( "VerticalAlign" ) ).get< style::VerticalAlignment >() ) + { + case style::VerticalAlignment_TOP: return excel::Constants::xlTop; + case style::VerticalAlignment_BOTTOM: return excel::Constants::xlBottom; + case style::VerticalAlignment_MIDDLE: return excel::Constants::xlCenter; + default:; + } + return excel::Constants::xlCenter; +} + +void SAL_CALL ScVbaButton::setVerticalAlignment( sal_Int32 nAlign ) throw (uno::RuntimeException) +{ + style::VerticalAlignment eAwtAlign = style::VerticalAlignment_MIDDLE; + switch( nAlign ) + { + case excel::Constants::xlTop: eAwtAlign = style::VerticalAlignment_TOP; break; + case excel::Constants::xlBottom: eAwtAlign = style::VerticalAlignment_BOTTOM; break; + case excel::Constants::xlCenter: eAwtAlign = style::VerticalAlignment_MIDDLE; break; + } + mxControlProps->setPropertyValue( CREATE_OUSTRING( "VerticalAlign" ), uno::Any( eAwtAlign ) ); +} + +sal_Int32 SAL_CALL ScVbaButton::getOrientation() throw (uno::RuntimeException) +{ + // not supported + return excel::XlOrientation::xlHorizontal; +} + +void SAL_CALL ScVbaButton::setOrientation( sal_Int32 /*nOrientation*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// XButton methods + +uno::Reference< excel::XCharacters > SAL_CALL ScVbaButton::Characters( const uno::Any& rStart, const uno::Any& rLength ) throw (uno::RuntimeException) +{ + return new ScVbaButtonCharacters( this, mxContext, mxControlProps, maPalette, rStart, rLength ); +} + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButton, "ooo.vba.excel.Button" ) + +// private + +OUString ScVbaButton::implGetBaseName() const +{ + return CREATE_OUSTRING( "Button" ); +} + +void ScVbaButton::implSetDefaultProperties() throw (uno::RuntimeException) +{ + setCaption( getName() ); +} + +// ============================================================================ diff --git a/sc/source/ui/vba/vbasheetobject.hxx b/sc/source/ui/vba/vbasheetobject.hxx new file mode 100755 index 000000000..a7af03630 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobject.hxx @@ -0,0 +1,220 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_SHEETOBJECT_HXX +#define SC_VBA_SHEETOBJECT_HXX + +#include <memory> +#include <ooo/vba/excel/XButton.hpp> +#include <ooo/vba/excel/XControlObject.hpp> +#include <ooo/vba/excel/XSheetObject.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "vbapalette.hxx" + +namespace com { namespace sun { namespace star { + namespace container { class XIndexContainer; } + namespace drawing { class XControlShape; } +} } } + +// ============================================================================ + +typedef InheritedHelperInterfaceImpl1< ov::excel::XCharacters > ScVbaButtonCharacters_BASE; + +/** Simple implementation of the Characters symbol for drawing button objects. */ +class ScVbaButtonCharacters : public ScVbaButtonCharacters_BASE +{ +public: + explicit ScVbaButtonCharacters( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::beans::XPropertySet >& rxPropSet, + const ScVbaPalette& rPalette, + const css::uno::Any& rStart, + const css::uno::Any& rLength ) throw (css::uno::RuntimeException); + virtual ~ScVbaButtonCharacters(); + + // XCharacters attributes + virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException); + virtual void SAL_CALL setCaption( const ::rtl::OUString& rCaption ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getText() throw (css::uno::RuntimeException); + virtual void SAL_CALL setText( const ::rtl::OUString& rText ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException); + virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) throw (css::uno::RuntimeException); + + // XCharacters methods + virtual void SAL_CALL Insert( const ::rtl::OUString& rString ) throw (css::uno::RuntimeException); + virtual void SAL_CALL Delete() throw (css::uno::RuntimeException); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +private: + ::rtl::OUString getFullString() const throw (css::uno::RuntimeException); + void setFullString( const ::rtl::OUString& rString ) throw (css::uno::RuntimeException); + +private: + ScVbaPalette maPalette; + css::uno::Reference< css::beans::XPropertySet > mxPropSet; + sal_Int32 mnStart; + sal_Int32 mnLength; +}; + +// ============================================================================ + +typedef InheritedHelperInterfaceImpl1< ov::excel::XSheetObject > ScVbaSheetObject_BASE; + +/** Base class for drawing objects embedded in sheets. */ +class ScVbaSheetObjectBase : public ScVbaSheetObject_BASE +{ +public: + explicit ScVbaSheetObjectBase( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::drawing::XShape >& rxShape ) throw (css::uno::RuntimeException); + + // XSheetObject attributes + virtual double SAL_CALL getLeft() throw (css::uno::RuntimeException); + virtual void SAL_CALL setLeft( double fLeft ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getTop() throw (css::uno::RuntimeException); + virtual void SAL_CALL setTop( double fTop ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getWidth() throw (css::uno::RuntimeException); + virtual void SAL_CALL setWidth( double fWidth ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getHeight() throw (css::uno::RuntimeException); + virtual void SAL_CALL setHeight( double fHeight ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getPlacement() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPlacement( sal_Int32 nPlacement ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getPrintObject() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) throw (css::uno::RuntimeException); + + /** Sets default properties after a new object has been created. */ + void setDefaultProperties( sal_Int32 nIndex ) throw (css::uno::RuntimeException); + +protected: + /** Derived classes return the base name used for new objects. */ + virtual ::rtl::OUString implGetBaseName() const = 0; + /** Derived classes set default properties for new drawing objects. */ + virtual void implSetDefaultProperties() throw (css::uno::RuntimeException); + +protected: + ScVbaPalette maPalette; + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::drawing::XShape > mxShape; + css::uno::Reference< css::beans::XPropertySet > mxShapeProps; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaSheetObjectBase, ov::excel::XControlObject > ScVbaControlObject_BASE; + +class ScVbaControlObjectBase : public ScVbaControlObject_BASE +{ +public: + /** Specifies the listener used for OnAction events. */ + enum ListenerType + { + LISTENER_ACTION, /// XActionListener.actionPerformed + LISTENER_MOUSE, /// XMouseListener.mouseReleased + LISTENER_TEXT, /// XTextListener.textChanged + LISTENER_VALUE, /// XAdjustmentListener.adjustmentValueChanged + LISTENER_CHANGE /// XChangeListener.changed + }; + + explicit ScVbaControlObjectBase( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::container::XIndexContainer >& rxFormIC, + const css::uno::Reference< css::drawing::XControlShape >& rxControlShape, + ListenerType eListenerType ) throw (css::uno::RuntimeException); + + // XSheetObject attributes + virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getOnAction() throw (css::uno::RuntimeException); + virtual void SAL_CALL setOnAction( const ::rtl::OUString& rMacroName ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getPrintObject() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) throw (css::uno::RuntimeException); + + // XControlObject attributes + virtual sal_Bool SAL_CALL getAutoSize() throw (css::uno::RuntimeException); + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) throw (css::uno::RuntimeException); + +protected: + sal_Int32 getModelIndexInForm() const throw (css::uno::RuntimeException); + +protected: + css::uno::Reference< css::container::XIndexContainer > mxFormIC; + css::uno::Reference< css::beans::XPropertySet > mxControlProps; + ::rtl::OUString maListenerType; + ::rtl::OUString maEventMethod; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaControlObjectBase, ov::excel::XButton > ScVbaButton_BASE; + +class ScVbaButton : public ScVbaButton_BASE +{ +public: + explicit ScVbaButton( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::container::XIndexContainer >& rxFormIC, + const css::uno::Reference< css::drawing::XControlShape >& rxControlShape ) throw (css::uno::RuntimeException); + + // XButton attributes + virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException); + virtual void SAL_CALL setCaption( const ::rtl::OUString& rCaption ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException); + virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getHorizontalAlignment() throw (css::uno::RuntimeException); + virtual void SAL_CALL setHorizontalAlignment( sal_Int32 nAlign ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getVerticalAlignment() throw (css::uno::RuntimeException); + virtual void SAL_CALL setVerticalAlignment( sal_Int32 nAlign ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getOrientation() throw (css::uno::RuntimeException); + virtual void SAL_CALL setOrientation( sal_Int32 nOrientation ) throw (css::uno::RuntimeException); + + // XButton methods + css::uno::Reference< ov::excel::XCharacters > SAL_CALL Characters( + const css::uno::Any& rStart, const css::uno::Any& rLength ) throw (css::uno::RuntimeException); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +protected: + virtual ::rtl::OUString implGetBaseName() const; + virtual void implSetDefaultProperties() throw (css::uno::RuntimeException); +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbasheetobjects.cxx b/sc/source/ui/vba/vbasheetobjects.cxx new file mode 100755 index 000000000..ba0d62b4c --- /dev/null +++ b/sc/source/ui/vba/vbasheetobjects.cxx @@ -0,0 +1,534 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbasheetobjects.hxx" +#include <vector> +#include <rtl/math.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/form/FormComponentType.hpp> +#include <com/sun/star/form/XForm.hpp> +#include <com/sun/star/form/XFormComponent.hpp> +#include <com/sun/star/form/XFormsSupplier.hpp> +#include <oox/helper/helper.hxx> +#include "vbasheetobject.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +// ============================================================================ + +namespace { + +template< typename Type > +inline bool lclGetProperty( Type& orValue, const uno::Reference< beans::XPropertySet >& rxPropSet, const OUString& rPropName ) +{ + try + { + return rxPropSet->getPropertyValue( rPropName ) >>= orValue; + } + catch( uno::Exception& ) + { + } + return false; +} + +/** Rounds the passed value to a multiple of 0.75 and converts it to 1/100 mm. */ +inline double lclPointsToHmm( const uno::Any& rPoints ) throw (uno::RuntimeException) +{ + return PointsToHmm( ::rtl::math::approxFloor( rPoints.get< double >() / 0.75 ) * 0.75 ); +} + +} // namespace + +// ============================================================================ +// Base implementations +// ============================================================================ + +/** Container for a specific type of drawing object in a spreadsheet. + + Derived classes provide all required functionality specific to the type of + shapes covered by the container. + */ +class ScVbaObjectContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess > +{ +public: + explicit ScVbaObjectContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType ) throw (uno::RuntimeException); + + /** Returns the VBA helper interface of the VBA collection object. */ + inline const uno::Reference< XHelperInterface >& getParent() const { return mxParent; } + /** Returns the component context of the VBA collection object. */ + inline const uno::Reference< uno::XComponentContext >& getContext() const { return mxContext; } + /** Returns the VBA type information of the objects in this container. */ + inline const uno::Type& getVbaType() const { return maVbaType; } + + /** Collects all shapes supported by this instance and inserts them into + the internal shape vector. */ + void collectShapes() throw (uno::RuntimeException); + /** Creates and returns a new UNO shape. */ + uno::Reference< drawing::XShape > createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException); + /** Inserts the passed shape into the draw page and into this container, and returns its index in the draw page. */ + sal_Int32 insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Creates and returns a new VBA implementation object for the passed shape. */ + ::rtl::Reference< ScVbaSheetObjectBase > createVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Creates and returns a new VBA implementation object for the passed shape in an Any. */ + uno::Any createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException); + /** Returns the VBA implementation object with the specified name. */ + uno::Any getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException); + virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); + + // XElementAccess + virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException); + +protected: + /** Derived classes return true, if the passed shape is supported by the instance. */ + virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const = 0; + /** Derived classes create and return a new VBA implementation object for the passed shape. */ + virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) = 0; + /** Derived classes return the service name of the UNO shape. */ + virtual OUString implGetShapeServiceName() const = 0; + + /** Returns the shape name via 'Name' property of the UNO shape. May be overwritten. */ + virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException); + /** Is called when a new UNO shape has been created but not yet inserted into the drawing page. */ + virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Is called when a new UNO shape has been inserted into the drawing page. */ + virtual void implOnShapeInserted( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + +protected: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxModel; + uno::Reference< lang::XMultiServiceFactory > mxFactory; + uno::Reference< drawing::XShapes > mxShapes; + +private: + typedef ::std::vector< uno::Reference< drawing::XShape > > ShapeVector; + const uno::Type maVbaType; + ShapeVector maShapes; +}; + +// ---------------------------------------------------------------------------- + +ScVbaObjectContainer::ScVbaObjectContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType ) throw (uno::RuntimeException) : + mxParent( rxParent ), + mxContext( rxContext ), + mxModel( rxModel, uno::UNO_SET_THROW ), + mxFactory( rxModel, uno::UNO_QUERY_THROW ), + maVbaType( rVbaType ) +{ + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( rxSheet, uno::UNO_QUERY_THROW ); + mxShapes.set( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW ); +} + +void ScVbaObjectContainer::collectShapes() throw (uno::RuntimeException) +{ + maShapes.clear(); + for( sal_Int32 nIndex = 0, nCount = mxShapes->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< drawing::XShape > xShape( mxShapes->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + if( implPickShape( xShape ) ) + maShapes.push_back( xShape ); + } +} + +uno::Reference< drawing::XShape > ScVbaObjectContainer::createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XShape > xShape( mxFactory->createInstance( implGetShapeServiceName() ), uno::UNO_QUERY_THROW ); + xShape->setPosition( rPos ); + xShape->setSize( rSize ); + implOnShapeCreated( xShape ); + return xShape; +} + +sal_Int32 ScVbaObjectContainer::insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + mxShapes->add( rxShape ); + maShapes.push_back( rxShape ); + implOnShapeInserted( rxShape ); + return mxShapes->getCount() - 1; +} + +::rtl::Reference< ScVbaSheetObjectBase > ScVbaObjectContainer::createVbaObject( + const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + return implCreateVbaObject( rxShape ); +} + +uno::Any ScVbaObjectContainer::createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XShape > xShape( rSource, uno::UNO_QUERY_THROW ); + uno::Reference< excel::XSheetObject > xSheetObject( implCreateVbaObject( xShape ) ); + return uno::Any( xSheetObject ); +} + +uno::Any ScVbaObjectContainer::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException) +{ + for( ShapeVector::iterator aIt = maShapes.begin(), aEnd = maShapes.end(); aIt != aEnd; ++aIt ) + if( rIndex == implGetShapeName( *aIt ) ) + return createCollectionObject( uno::Any( *aIt ) ); + throw uno::RuntimeException(); +} + +// XIndexAccess + +sal_Int32 SAL_CALL ScVbaObjectContainer::getCount() throw (uno::RuntimeException) +{ + return static_cast< sal_Int32 >( maShapes.size() ); +} + +uno::Any SAL_CALL ScVbaObjectContainer::getByIndex( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) +{ + if( (0 <= nIndex) && (nIndex < getCount()) ) + return uno::Any( maShapes[ static_cast< size_t >( nIndex ) ] ); + throw lang::IndexOutOfBoundsException(); +} + +// XElementAccess + +uno::Type SAL_CALL ScVbaObjectContainer::getElementType() throw (uno::RuntimeException) +{ + return drawing::XShape::static_type( 0 ); +} + +sal_Bool SAL_CALL ScVbaObjectContainer::hasElements() throw (uno::RuntimeException) +{ + return !maShapes.empty(); +} + +// private + +OUString ScVbaObjectContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException) +{ + uno::Reference< beans::XPropertySet > xPropSet( rxShape, uno::UNO_QUERY_THROW ); + return xPropSet->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void ScVbaObjectContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException) +{ +} + +void ScVbaObjectContainer::implOnShapeInserted( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException) +{ +} + +// ============================================================================ + +class ScVbaObjectEnumeration : public SimpleEnumerationBase +{ +public: + explicit ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ); + virtual uno::Any createCollectionObject( const uno::Any& rSource ); + +private: + ScVbaObjectContainerRef mxContainer; +}; + +// ---------------------------------------------------------------------------- + +ScVbaObjectEnumeration::ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ) : + SimpleEnumerationBase( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ), + mxContainer( rxContainer ) +{ +} + +uno::Any ScVbaObjectEnumeration::createCollectionObject( const uno::Any& rSource ) +{ + return mxContainer->createCollectionObject( rSource ); +} + +// ============================================================================ + +ScVbaSheetObjectsBase::ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException) : + ScVbaSheetObjects_BASE( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ), + mxContainer( rxContainer ) +{ + mxContainer->collectShapes(); +} + +ScVbaSheetObjectsBase::~ScVbaSheetObjectsBase() +{ +} + +void ScVbaSheetObjectsBase::collectShapes() throw (uno::RuntimeException) +{ + mxContainer->collectShapes(); +} + +// XEnumerationAccess + +uno::Reference< container::XEnumeration > SAL_CALL ScVbaSheetObjectsBase::createEnumeration() throw (uno::RuntimeException) +{ + return new ScVbaObjectEnumeration( mxContainer ); +} + +// XElementAccess + +uno::Type SAL_CALL ScVbaSheetObjectsBase::getElementType() throw (uno::RuntimeException) +{ + return mxContainer->getVbaType(); +} + +// ScVbaCollectionBase + +uno::Any ScVbaSheetObjectsBase::createCollectionObject( const uno::Any& rSource ) +{ + return mxContainer->createCollectionObject( rSource ); +} + +uno::Any ScVbaSheetObjectsBase::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException) +{ + return mxContainer->getItemByStringIndex( rIndex ); +} + +// ============================================================================ +// Graphic object containers supporting ooo.vba.excel.XGraphicObject +// ============================================================================ + +ScVbaGraphicObjectsBase::ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (uno::RuntimeException) : + ScVbaGraphicObjects_BASE( rxContainer ) +{ +} + +// XGraphicObjects + +uno::Any SAL_CALL ScVbaGraphicObjectsBase::Add( const uno::Any& rLeft, const uno::Any& rTop, const uno::Any& rWidth, const uno::Any& rHeight ) throw (uno::RuntimeException) +{ + /* Extract double values from passed Anys (the lclPointsToHmm() helper + function will throw a RuntimeException on any error), and convert from + points to 1/100 mm. */ + awt::Point aPos( lclPointsToHmm( rLeft ), lclPointsToHmm( rTop ) ); + awt::Size aSize( lclPointsToHmm( rWidth ), lclPointsToHmm( rHeight ) ); + // TODO: translate coordinates for RTL sheets + if( (aPos.X < 0) || (aPos.Y < 0) || (aSize.Width <= 0) || (aSize.Height <= 0) ) + throw uno::RuntimeException(); + + // create the UNO shape + uno::Reference< drawing::XShape > xShape( mxContainer->createShape( aPos, aSize ), uno::UNO_SET_THROW ); + sal_Int32 nIndex = mxContainer->insertShape( xShape ); + + // create and return the VBA object + ::rtl::Reference< ScVbaSheetObjectBase > xVbaObject = mxContainer->createVbaObject( xShape ); + xVbaObject->setDefaultProperties( nIndex ); + return uno::Any( uno::Reference< excel::XSheetObject >( xVbaObject.get() ) ); +} + +// ============================================================================ +// Drawing controls +// ============================================================================ + +class ScVbaControlContainer : public ScVbaObjectContainer +{ +public: + explicit ScVbaControlContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType, + const OUString& rModelServiceName, + sal_Int16 nComponentType ) throw (uno::RuntimeException); + +protected: + uno::Reference< container::XIndexContainer > createForm() throw (uno::RuntimeException); + + virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const; + virtual OUString implGetShapeServiceName() const; + virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const; + virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException); + virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + +protected: + uno::Reference< container::XIndexContainer > mxFormIC; + OUString maModelServiceName; + sal_Int16 mnComponentType; +}; + +// ---------------------------------------------------------------------------- + +ScVbaControlContainer::ScVbaControlContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType, + const OUString& rModelServiceName, + sal_Int16 nComponentType ) throw (uno::RuntimeException) : + ScVbaObjectContainer( rxParent, rxContext, rxModel, rxSheet, rVbaType ), + maModelServiceName( rModelServiceName ), + mnComponentType( nComponentType ) +{ +} + +uno::Reference< container::XIndexContainer > ScVbaControlContainer::createForm() throw (uno::RuntimeException) +{ + if( !mxFormIC.is() ) + { + uno::Reference< form::XFormsSupplier > xFormsSupp( mxShapes, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameContainer > xFormsNC( xFormsSupp->getForms(), uno::UNO_SET_THROW ); + OUString aFormName = CREATE_OUSTRING( "Standard" ); + if( xFormsNC->hasByName( aFormName ) ) + { + mxFormIC.set( xFormsNC->getByName( aFormName ), uno::UNO_QUERY_THROW ); + } + else + { + uno::Reference< form::XForm > xForm( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), uno::UNO_QUERY_THROW ); + xFormsNC->insertByName( aFormName, uno::Any( xForm ) ); + mxFormIC.set( xForm, uno::UNO_QUERY_THROW ); + } + } + return mxFormIC; +} + +bool ScVbaControlContainer::implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const +{ + try + { + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xModelProps( xControlShape->getControl(), uno::UNO_QUERY_THROW ); + sal_Int16 nClassId = -1; + return lclGetProperty( nClassId, xModelProps, CREATE_OUSTRING( "ClassId" ) ) && + (nClassId == mnComponentType) && implCheckProperties( xModelProps ); + } + catch( uno::Exception& ) + { + } + return false; +} + +OUString ScVbaControlContainer::implGetShapeServiceName() const +{ + return CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ); +} + +bool ScVbaControlContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& /*rxModelProps*/ ) const +{ + return true; +} + +OUString ScVbaControlContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException) +{ + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + return uno::Reference< container::XNamed >( xControlShape->getControl(), uno::UNO_QUERY_THROW )->getName(); +} + +void ScVbaControlContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + // passed shape must be a control shape + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + + // create the UNO control model + uno::Reference< form::XFormComponent > xFormComponent( mxFactory->createInstance( maModelServiceName ), uno::UNO_QUERY_THROW ); + uno::Reference< awt::XControlModel > xControlModel( xFormComponent, uno::UNO_QUERY_THROW ); + + // insert the control model into the form and the shape + createForm(); + mxFormIC->insertByIndex( mxFormIC->getCount(), uno::Any( xFormComponent ) ); + xControlShape->setControl( xControlModel ); +} + +// ============================================================================ +// Push button +// ============================================================================ + +class ScVbaButtonContainer : public ScVbaControlContainer +{ +public: + explicit ScVbaButtonContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException); + +protected: + virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const; +}; + +// ---------------------------------------------------------------------------- + +ScVbaButtonContainer::ScVbaButtonContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) : + ScVbaControlContainer( + rxParent, rxContext, rxModel, rxSheet, + excel::XButton::static_type( 0 ), + CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" ), + form::FormComponentType::COMMANDBUTTON ) +{ +} + +ScVbaSheetObjectBase* ScVbaButtonContainer::implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + return new ScVbaButton( mxParent, mxContext, mxModel, createForm(), xControlShape ); +} + +bool ScVbaButtonContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const +{ + // do not insert toggle buttons into the 'Buttons' collection + bool bToggle = false; + return lclGetProperty( bToggle, rxModelProps, CREATE_OUSTRING( "Toggle" ) ) && !bToggle; +} + +// ============================================================================ + +ScVbaButtons::ScVbaButtons( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) : + ScVbaGraphicObjectsBase( new ScVbaButtonContainer( rxParent, rxContext, rxModel, rxSheet ) ) +{ +} + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtons, "ooo.vba.excel.Buttons" ) + +// ============================================================================ diff --git a/sc/source/ui/vba/vbasheetobjects.hxx b/sc/source/ui/vba/vbasheetobjects.hxx new file mode 100755 index 000000000..ba6eb8c5f --- /dev/null +++ b/sc/source/ui/vba/vbasheetobjects.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_SHEETOBJECTS_HXX +#define SC_VBA_SHEETOBJECTS_HXX + +#include <ooo/vba/excel/XGraphicObjects.hpp> +#include <vbahelper/vbacollectionimpl.hxx> +#include <rtl/ref.hxx> + +namespace com { namespace sun { namespace star { + namespace container { class XEnumeration; } + namespace frame { class XModel; } + namespace sheet { class XSpreadsheet; } +} } } + +// ============================================================================ + +class ScVbaObjectContainer; +typedef ::rtl::Reference< ScVbaObjectContainer > ScVbaObjectContainerRef; + +// ============================================================================ + +typedef CollTestImplHelper< ov::XCollection > ScVbaSheetObjects_BASE; + +/** Base class for collections containing a specific type of drawing object + embedded in a sheet (worksheet, chart sheet, or dialog sheet). + */ +class ScVbaSheetObjectsBase : public ScVbaSheetObjects_BASE +{ +public: + explicit ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException); + virtual ~ScVbaSheetObjectsBase(); + + /** Updates the collection by fetching all shapes from the draw page. */ + void collectShapes() throw (css::uno::RuntimeException); + + // XEnumerationAccess + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException); + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); + + // ScVbaCollectionBase + virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ); + virtual css::uno::Any getItemByStringIndex( const ::rtl::OUString& rIndex ) throw (css::uno::RuntimeException); + +protected: + ScVbaObjectContainerRef mxContainer; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaSheetObjectsBase, ov::excel::XGraphicObjects > ScVbaGraphicObjects_BASE; + +/** Base class for collections containing a specific type of graphic object + from a sheet. + */ +class ScVbaGraphicObjectsBase : public ScVbaGraphicObjects_BASE +{ +public: + explicit ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException); + + // XGraphicObjects + virtual css::uno::Any SAL_CALL Add( + const css::uno::Any& rLeft, + const css::uno::Any& rTop, + const css::uno::Any& rWidth, + const css::uno::Any& rHeight ) throw (css::uno::RuntimeException); +}; + +// ============================================================================ + +/** Collection containing all button controls from a sheet (not ActiveX controls). */ +class ScVbaButtons : public ScVbaGraphicObjectsBase +{ +public: + explicit ScVbaButtons( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::sheet::XSpreadsheet >& rxSheet ) throw (css::uno::RuntimeException); + + VBAHELPER_DECL_XHELPERINTERFACE +}; + +// ============================================================================ + +#endif |