xref: /trunk/main/sc/source/ui/vba/vbawindows.cxx (revision cdf0e10c)
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