1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #include "vbawindows.hxx" 28 29 #include <hash_map> 30 31 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> 32 #include <com/sun/star/frame/XDesktop.hpp> 33 #include <cppuhelper/implbase3.hxx> 34 35 #include <tools/urlobj.hxx> 36 #include "vbawindow.hxx" 37 #include "vbaglobals.hxx" 38 //#include "vbaworkbook.hxx" 39 40 using namespace ::com::sun::star; 41 using namespace ::ooo::vba; 42 43 typedef std::hash_map< rtl::OUString, 44 sal_Int32, ::rtl::OUStringHash, 45 ::std::equal_to< ::rtl::OUString > > NameIndexHash; 46 47 48 uno::Reference< XHelperInterface > lcl_createWorkbookHIParent( const uno::Reference< frame::XModel >& xModel, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any& aApplication ) 49 { 50 return new ScVbaWorkbook( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xModel ); 51 } 52 53 uno::Any ComponentToWindow( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext, const uno::Any& aApplication ) 54 { 55 uno::Reference< frame::XModel > xModel( aSource, uno::UNO_QUERY_THROW ); 56 // !! TODO !! iterate over all controllers 57 uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); 58 uno::Reference< excel::XWindow > xWin( new ScVbaWindow( lcl_createWorkbookHIParent( xModel, xContext, aApplication ), xContext, xModel, xController ) ); 59 return uno::makeAny( xWin ); 60 } 61 62 typedef std::vector < uno::Reference< sheet::XSpreadsheetDocument > > Components; 63 // #TODO more or less the same as class in workwindows ( code sharing needed ) 64 class WindowComponentEnumImpl : public EnumerationHelper_BASE 65 { 66 protected: 67 uno::Reference< uno::XComponentContext > m_xContext; 68 Components m_components; 69 Components::const_iterator m_it; 70 71 public: 72 WindowComponentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const Components& components ) throw ( uno::RuntimeException ) : m_xContext( xContext ), m_components( components ) 73 { 74 m_it = m_components.begin(); 75 } 76 77 WindowComponentEnumImpl( const uno::Reference< uno::XComponentContext >& xContext ) throw ( uno::RuntimeException ) : m_xContext( xContext ) 78 { 79 uno::Reference< lang::XMultiComponentFactory > xSMgr( 80 m_xContext->getServiceManager(), uno::UNO_QUERY_THROW ); 81 82 uno::Reference< frame::XDesktop > xDesktop 83 (xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop"), m_xContext), uno::UNO_QUERY_THROW ); 84 uno::Reference< container::XEnumeration > mxComponents = xDesktop->getComponents()->createEnumeration(); 85 while( mxComponents->hasMoreElements() ) 86 { 87 uno::Reference< sheet::XSpreadsheetDocument > xNext( mxComponents->nextElement(), uno::UNO_QUERY ); 88 if ( xNext.is() ) 89 m_components.push_back( xNext ); 90 } 91 m_it = m_components.begin(); 92 } 93 // XEnumeration 94 virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException) 95 { 96 return m_it != m_components.end(); 97 } 98 99 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 100 { 101 if ( !hasMoreElements() ) 102 { 103 throw container::NoSuchElementException(); 104 } 105 return makeAny( *(m_it++) ); 106 } 107 }; 108 109 class WindowEnumImpl : public WindowComponentEnumImpl 110 { 111 uno::Any m_aApplication; 112 public: 113 WindowEnumImpl(const uno::Reference< uno::XComponentContext >& xContext, const Components& components, const uno::Any& aApplication ):WindowComponentEnumImpl( xContext, components ), m_aApplication( aApplication ){} 114 WindowEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Any& aApplication ): WindowComponentEnumImpl( xContext ), m_aApplication( aApplication ) {} 115 virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 116 { 117 return ComponentToWindow( WindowComponentEnumImpl::nextElement(), m_xContext, m_aApplication ); 118 } 119 }; 120 121 typedef ::cppu::WeakImplHelper3< container::XEnumerationAccess 122 , com::sun::star::container::XIndexAccess 123 , com::sun::star::container::XNameAccess 124 > WindowsAccessImpl_BASE; 125 126 class WindowsAccessImpl : public WindowsAccessImpl_BASE 127 { 128 uno::Reference< uno::XComponentContext > m_xContext; 129 Components m_windows; 130 NameIndexHash namesToIndices; 131 public: 132 WindowsAccessImpl( const uno::Reference< uno::XComponentContext >& xContext ):m_xContext( xContext ) 133 { 134 uno::Reference< container::XEnumeration > xEnum = new WindowComponentEnumImpl( m_xContext ); 135 sal_Int32 nIndex=0; 136 while( xEnum->hasMoreElements() ) 137 { 138 uno::Reference< sheet::XSpreadsheetDocument > xNext( xEnum->nextElement(), uno::UNO_QUERY ); 139 if ( xNext.is() ) 140 { 141 m_windows.push_back( xNext ); 142 uno::Reference< frame::XModel > xModel( xNext, uno::UNO_QUERY_THROW ); // that the spreadsheetdocument is a xmodel is a given 143 // !! TODO !! iterate over all controllers 144 uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); 145 uno::Reference< XHelperInterface > xTemp; // temporary needed for g++ 3.3.5 146 ScVbaWindow window( xTemp, m_xContext, xModel, xController ); 147 rtl::OUString sCaption; 148 window.getCaption() >>= sCaption; 149 namesToIndices[ sCaption ] = nIndex++; 150 } 151 } 152 153 } 154 155 //XEnumerationAccess 156 virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration( ) throw (uno::RuntimeException) 157 { 158 return new WindowComponentEnumImpl( m_xContext, m_windows ); 159 } 160 // XIndexAccess 161 virtual ::sal_Int32 SAL_CALL getCount( ) throw (uno::RuntimeException) 162 { 163 return m_windows.size(); 164 } 165 virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw ( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) 166 { 167 if ( Index < 0 168 || static_cast< Components::size_type >( Index ) >= m_windows.size() ) 169 throw lang::IndexOutOfBoundsException(); 170 return makeAny( m_windows[ Index ] ); // returns xspreadsheetdoc 171 } 172 173 //XElementAccess 174 virtual uno::Type SAL_CALL getElementType( ) throw (uno::RuntimeException) 175 { 176 return sheet::XSpreadsheetDocument::static_type(0); 177 } 178 179 virtual ::sal_Bool SAL_CALL hasElements( ) throw (uno::RuntimeException) 180 { 181 return (m_windows.size() > 0); 182 } 183 184 //XNameAccess 185 virtual uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 186 { 187 NameIndexHash::const_iterator it = namesToIndices.find( aName ); 188 if ( it == namesToIndices.end() ) 189 throw container::NoSuchElementException(); 190 return makeAny( m_windows[ it->second ] ); 191 192 } 193 194 virtual uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (uno::RuntimeException) 195 { 196 uno::Sequence< ::rtl::OUString > names( namesToIndices.size() ); 197 ::rtl::OUString* pString = names.getArray(); 198 NameIndexHash::const_iterator it = namesToIndices.begin(); 199 NameIndexHash::const_iterator it_end = namesToIndices.end(); 200 for ( ; it != it_end; ++it, ++pString ) 201 *pString = it->first; 202 return names; 203 } 204 205 virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException) 206 { 207 NameIndexHash::const_iterator it = namesToIndices.find( aName ); 208 return (it != namesToIndices.end()); 209 } 210 211 }; 212 213 214 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 ) 215 { 216 } 217 218 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 ) ) ) 219 { 220 } 221 uno::Reference< container::XEnumeration > 222 ScVbaWindows::createEnumeration() throw (uno::RuntimeException) 223 { 224 return new WindowEnumImpl( mxContext, Application() ); 225 } 226 227 uno::Any 228 ScVbaWindows::createCollectionObject( const css::uno::Any& aSource ) 229 { 230 return ComponentToWindow( aSource, mxContext, Application() ); 231 } 232 233 uno::Type 234 ScVbaWindows::getElementType() throw (uno::RuntimeException) 235 { 236 return excel::XWindows::static_type(0); 237 } 238 239 240 void SAL_CALL 241 ScVbaWindows::Arrange( ::sal_Int32 /*ArrangeStyle*/, const uno::Any& /*ActiveWorkbook*/, const uno::Any& /*SyncHorizontal*/, const uno::Any& /*SyncVertical*/ ) throw (uno::RuntimeException) 242 { 243 //#TODO #FIXME see what can be done for an implementation here 244 } 245 246 247 rtl::OUString& 248 ScVbaWindows::getServiceImplName() 249 { 250 static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWindows") ); 251 return sImplName; 252 } 253 254 css::uno::Sequence<rtl::OUString> 255 ScVbaWindows::getServiceNames() 256 { 257 static uno::Sequence< rtl::OUString > sNames; 258 if ( sNames.getLength() == 0 ) 259 { 260 sNames.realloc( 1 ); 261 sNames[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Windows") ); 262 } 263 return sNames; 264 } 265