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