| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| #include "vbawindows.hxx" |
| |
| #include <hash_map> |
| |
| #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> |
| #include <com/sun/star/frame/XDesktop.hpp> |
| #include <cppuhelper/implbase3.hxx> |
| |
| #include <tools/urlobj.hxx> |
| #include "vbawindow.hxx" |
| #include "vbaglobals.hxx" |
| //#include "vbaworkbook.hxx" |
| |
| using namespace ::com::sun::star; |
| using namespace ::ooo::vba; |
| |
| typedef std::hash_map< rtl::OUString, |
| sal_Int32, ::rtl::OUStringHash, |
| ::std::equal_to< ::rtl::OUString > > NameIndexHash; |
| |
| |
| uno::Reference< XHelperInterface > lcl_createWorkbookHIParent( const uno::Reference< frame::XModel >& xModel, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any& aApplication ) |
| { |
| return new ScVbaWorkbook( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xModel ); |
| } |
| |
| uno::Any ComponentToWindow( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext, const uno::Any& aApplication ) |
| { |
| uno::Reference< frame::XModel > xModel( aSource, uno::UNO_QUERY_THROW ); |
| // !! TODO !! iterate over all controllers |
| uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); |
| uno::Reference< excel::XWindow > xWin( new ScVbaWindow( lcl_createWorkbookHIParent( xModel, xContext, aApplication ), xContext, xModel, xController ) ); |
| return uno::makeAny( xWin ); |
| } |
| |
| typedef std::vector < uno::Reference< sheet::XSpreadsheetDocument > > Components; |
| // #TODO more or less the same as class in workwindows ( code sharing needed ) |
| class WindowComponentEnumImpl : public EnumerationHelper_BASE |
| { |
| protected: |
| uno::Reference< uno::XComponentContext > m_xContext; |
| Components m_components; |
| Components::const_iterator m_it; |
| |
| public: |
| WindowComponentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const Components& components ) throw ( uno::RuntimeException ) : m_xContext( xContext ), m_components( components ) |
| { |
| m_it = m_components.begin(); |
| } |
| |
| WindowComponentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext ) throw ( uno::RuntimeException ) : m_xContext( xContext ) |
| { |
| uno::Reference< lang::XMultiComponentFactory > xSMgr( |
| m_xContext->getServiceManager(), uno::UNO_QUERY_THROW ); |
| |
| uno::Reference< frame::XDesktop > xDesktop |
| (xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop"), m_xContext), uno::UNO_QUERY_THROW ); |
| uno::Reference< container::XEnumeration > mxComponents = xDesktop->getComponents()->createEnumeration(); |
| while( mxComponents->hasMoreElements() ) |
| { |
| uno::Reference< sheet::XSpreadsheetDocument > xNext( mxComponents->nextElement(), uno::UNO_QUERY ); |
| if ( xNext.is() ) |
| m_components.push_back( xNext ); |
| } |
| m_it = m_components.begin(); |
| } |
| // XEnumeration |
| virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException) |
| { |
| return m_it != m_components.end(); |
| } |
| |
| virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) |
| { |
| if ( !hasMoreElements() ) |
| { |
| throw container::NoSuchElementException(); |
| } |
| return makeAny( *(m_it++) ); |
| } |
| }; |
| |
| class WindowEnumImpl : public WindowComponentEnumImpl |
| { |
| uno::Any m_aApplication; |
| public: |
| WindowEnumImpl(const uno::Reference< uno::XComponentContext >& xContext, const Components& components, const uno::Any& aApplication ):WindowComponentEnumImpl( xContext, components ), m_aApplication( aApplication ){} |
| WindowEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Any& aApplication ): WindowComponentEnumImpl( xContext ), m_aApplication( aApplication ) {} |
| virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) |
| { |
| return ComponentToWindow( WindowComponentEnumImpl::nextElement(), m_xContext, m_aApplication ); |
| } |
| }; |
| |
| typedef ::cppu::WeakImplHelper3< container::XEnumerationAccess |
| , com::sun::star::container::XIndexAccess |
| , com::sun::star::container::XNameAccess |
| > WindowsAccessImpl_BASE; |
| |
| class WindowsAccessImpl : public WindowsAccessImpl_BASE |
| { |
| uno::Reference< uno::XComponentContext > m_xContext; |
| Components m_windows; |
| NameIndexHash namesToIndices; |
| public: |
| WindowsAccessImpl( const uno::Reference< uno::XComponentContext >& xContext ):m_xContext( xContext ) |
| { |
| uno::Reference< container::XEnumeration > xEnum = new WindowComponentEnumImpl( m_xContext ); |
| sal_Int32 nIndex=0; |
| while( xEnum->hasMoreElements() ) |
| { |
| uno::Reference< sheet::XSpreadsheetDocument > xNext( xEnum->nextElement(), uno::UNO_QUERY ); |
| if ( xNext.is() ) |
| { |
| m_windows.push_back( xNext ); |
| uno::Reference< frame::XModel > xModel( xNext, uno::UNO_QUERY_THROW ); // that the spreadsheetdocument is a xmodel is a given |
| // !! TODO !! iterate over all controllers |
| uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); |
| uno::Reference< XHelperInterface > xTemp; // temporary needed for g++ 3.3.5 |
| ScVbaWindow window( xTemp, m_xContext, xModel, xController ); |
| rtl::OUString sCaption; |
| window.getCaption() >>= sCaption; |
| namesToIndices[ sCaption ] = nIndex++; |
| } |
| } |
| |
| } |
| |
| //XEnumerationAccess |
| virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) throw (uno::RuntimeException) |
| { |
| return new WindowComponentEnumImpl( m_xContext, m_windows ); |
| } |
| // XIndexAccess |
| virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException) |
| { |
| return m_windows.size(); |
| } |
| virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw ( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) |
| { |
| if ( Index < 0 |
| || static_cast< Components::size_type >( Index ) >= m_windows.size() ) |
| throw lang::IndexOutOfBoundsException(); |
| return makeAny( m_windows[ Index ] ); // returns xspreadsheetdoc |
| } |
| |
| //XElementAccess |
| virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) |
| { |
| return sheet::XSpreadsheetDocument::static_type(0); |
| } |
| |
| virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException) |
| { |
| return (m_windows.size() > 0); |
| } |
| |
| //XNameAccess |
| virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) |
| { |
| NameIndexHash::const_iterator it = namesToIndices.find( aName ); |
| if ( it == namesToIndices.end() ) |
| throw container::NoSuchElementException(); |
| return makeAny( m_windows[ it->second ] ); |
| |
| } |
| |
| virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException) |
| { |
| uno::Sequence< ::rtl::OUString > names( namesToIndices.size() ); |
| ::rtl::OUString* pString = names.getArray(); |
| NameIndexHash::const_iterator it = namesToIndices.begin(); |
| NameIndexHash::const_iterator it_end = namesToIndices.end(); |
| for ( ; it != it_end; ++it, ++pString ) |
| *pString = it->first; |
| return names; |
| } |
| |
| virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException) |
| { |
| NameIndexHash::const_iterator it = namesToIndices.find( aName ); |
| return (it != namesToIndices.end()); |
| } |
| |
| }; |
| |
| |
| ScVbaWindows::ScVbaWindows( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ): ScVbaWindows_BASE( xParent, xContext, xIndexAccess ) |
| { |
| } |
| |
| ScVbaWindows::ScVbaWindows( const uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : ScVbaWindows_BASE( xParent, xContext, uno::Reference< container::XIndexAccess > ( new WindowsAccessImpl( xContext ) ) ) |
| { |
| } |
| uno::Reference< container::XEnumeration > |
| ScVbaWindows::createEnumeration() throw (uno::RuntimeException) |
| { |
| return new WindowEnumImpl( mxContext, Application() ); |
| } |
| |
| uno::Any |
| ScVbaWindows::createCollectionObject( const css::uno::Any& aSource ) |
| { |
| return ComponentToWindow( aSource, mxContext, Application() ); |
| } |
| |
| uno::Type |
| ScVbaWindows::getElementType() throw (uno::RuntimeException) |
| { |
| return excel::XWindows::static_type(0); |
| } |
| |
| |
| void SAL_CALL |
| ScVbaWindows::Arrange( ::sal_Int32 /*ArrangeStyle*/, const uno::Any& /*ActiveWorkbook*/, const uno::Any& /*SyncHorizontal*/, const uno::Any& /*SyncVertical*/ ) throw (uno::RuntimeException) |
| { |
| //#TODO #FIXME see what can be done for an implementation here |
| } |
| |
| |
| rtl::OUString& |
| ScVbaWindows::getServiceImplName() |
| { |
| static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWindows") ); |
| return sImplName; |
| } |
| |
| css::uno::Sequence<rtl::OUString> |
| ScVbaWindows::getServiceNames() |
| { |
| static uno::Sequence< rtl::OUString > sNames; |
| if ( sNames.getLength() == 0 ) |
| { |
| sNames.realloc( 1 ); |
| sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Windows") ); |
| } |
| return sNames; |
| } |