1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "vbawindows.hxx"
22 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
23 #include <com/sun/star/frame/Desktop.hpp>
24 #include <cppuhelper/implbase.hxx>
25 #include <comphelper/sequence.hxx>
26 #include <o3tl/safeint.hxx>
27 #include <rtl/ref.hxx>
29 #include "vbawindow.hxx"
30 #include "vbaworkbook.hxx"
32 #include <unordered_map>
35 #include <osl/file.hxx>
36 #include <ooo/vba/excel/XApplication.hpp>
38 using namespace ::com::sun::star
;
39 using namespace ::ooo::vba
;
41 typedef std::unordered_map
< OUString
,
42 sal_Int32
> NameIndexHash
;
44 static uno::Reference
< XHelperInterface
> lcl_createWorkbookHIParent( const uno::Reference
< frame::XModel
>& xModel
, const uno::Reference
< uno::XComponentContext
>& xContext
, const uno::Any
& aApplication
)
46 return new ScVbaWorkbook( uno::Reference
< XHelperInterface
>( aApplication
, uno::UNO_QUERY_THROW
), xContext
, xModel
);
49 static uno::Any
ComponentToWindow( const uno::Any
& aSource
, const uno::Reference
< uno::XComponentContext
> & xContext
, const uno::Any
& aApplication
)
51 uno::Reference
< frame::XModel
> xModel( aSource
, uno::UNO_QUERY_THROW
);
52 // !! TODO !! iterate over all controllers
53 uno::Reference
< frame::XController
> xController( xModel
->getCurrentController(), uno::UNO_SET_THROW
);
54 uno::Reference
< excel::XWindow
> xWin( new ScVbaWindow( lcl_createWorkbookHIParent( xModel
, xContext
, aApplication
), xContext
, xModel
, xController
) );
55 return uno::Any( xWin
);
58 typedef std::vector
< uno::Reference
< sheet::XSpreadsheetDocument
> > Components
;
62 // #TODO more or less the same as class in workwindows ( code sharing needed )
63 class WindowComponentEnumImpl
: public EnumerationHelper_BASE
66 uno::Reference
< uno::XComponentContext
> m_xContext
;
67 Components m_components
;
68 Components::const_iterator m_it
;
71 /// @throws uno::RuntimeException
72 WindowComponentEnumImpl( uno::Reference
< uno::XComponentContext
> xContext
, Components
&& components
)
73 : m_xContext(std::move( xContext
)), m_components( std::move(components
) )
75 m_it
= m_components
.begin();
78 /// @throws uno::RuntimeException
79 explicit WindowComponentEnumImpl( uno::Reference
< uno::XComponentContext
> xContext
) : m_xContext(std::move( xContext
))
81 uno::Reference
< frame::XDesktop2
> xDesktop
= frame::Desktop::create(m_xContext
);
82 uno::Reference
< container::XEnumeration
> xComponents
= xDesktop
->getComponents()->createEnumeration();
83 while( xComponents
->hasMoreElements() )
85 uno::Reference
< sheet::XSpreadsheetDocument
> xNext( xComponents
->nextElement(), uno::UNO_QUERY
);
87 m_components
.push_back( xNext
);
89 m_it
= m_components
.begin();
92 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
94 return m_it
!= m_components
.end();
97 virtual uno::Any SAL_CALL
nextElement( ) override
99 if ( !hasMoreElements() )
101 throw container::NoSuchElementException();
103 return css::uno::Any( *(m_it
++) );
107 class WindowEnumImpl
: public WindowComponentEnumImpl
109 uno::Any m_aApplication
;
111 WindowEnumImpl( const uno::Reference
< uno::XComponentContext
>& xContext
, uno::Any aApplication
): WindowComponentEnumImpl( xContext
), m_aApplication(std::move( aApplication
)) {}
112 virtual uno::Any SAL_CALL
nextElement( ) override
114 return ComponentToWindow( WindowComponentEnumImpl::nextElement(), m_xContext
, m_aApplication
);
120 typedef ::cppu::WeakImplHelper
< container::XEnumerationAccess
121 , css::container::XIndexAccess
122 , css::container::XNameAccess
123 > WindowsAccessImpl_BASE
;
127 class WindowsAccessImpl
: public WindowsAccessImpl_BASE
129 uno::Reference
< uno::XComponentContext
> m_xContext
;
130 Components m_windows
;
131 NameIndexHash namesToIndices
;
133 explicit WindowsAccessImpl( uno::Reference
< uno::XComponentContext
> xContext
):m_xContext(std::move( xContext
))
135 css::uno::Reference
<css::container::XNameAccess
> xNameAccess(m_xContext
,
136 css::uno::UNO_QUERY_THROW
);
137 const auto aAppplication
= xNameAccess
->getByName(u
"Application"_ustr
);
139 uno::Reference
< container::XEnumeration
> xEnum
= new WindowComponentEnumImpl( m_xContext
);
141 while( xEnum
->hasMoreElements() )
143 uno::Reference
< sheet::XSpreadsheetDocument
> xNext( xEnum
->nextElement(), uno::UNO_QUERY
);
146 m_windows
.push_back( xNext
);
147 uno::Reference
< frame::XModel
> xModel( xNext
, uno::UNO_QUERY_THROW
); // that the spreadsheetdocument is a xmodel is a given
149 // tdf#126457 - add workbook name to window titles
150 rtl::Reference
<ScVbaWorkbook
> workbook(new ScVbaWorkbook(
151 uno::Reference
<XHelperInterface
>(aAppplication
, uno::UNO_QUERY_THROW
),
152 m_xContext
, xModel
));
153 const OUString
aWorkBookName(workbook
->getName());
154 if (!hasByName(aWorkBookName
))
155 namesToIndices
[aWorkBookName
] = nIndex
;
157 // tdf#126457 - add file url to window titles
159 ::osl::File::getSystemPathFromFileURL(xModel
->getURL(), sName
);
160 if (!hasByName(sName
))
161 namesToIndices
[sName
] = nIndex
;
163 // !! TODO !! iterate over all controllers
164 uno::Reference
< frame::XController
> xController( xModel
->getCurrentController(), uno::UNO_SET_THROW
);
165 uno::Reference
< XHelperInterface
> xTemp
; // temporary needed for g++ 3.3.5
166 rtl::Reference
< ScVbaWindow
> window( new ScVbaWindow( xTemp
, m_xContext
, xModel
, xController
) );
168 window
->getCaption() >>= sCaption
;
169 namesToIndices
[ sCaption
] = nIndex
++;
176 virtual uno::Reference
< container::XEnumeration
> SAL_CALL
createEnumeration( ) override
178 return new WindowComponentEnumImpl( m_xContext
, std::vector(m_windows
) );
181 virtual ::sal_Int32 SAL_CALL
getCount( ) override
183 return m_windows
.size();
185 virtual uno::Any SAL_CALL
getByIndex( ::sal_Int32 Index
) override
188 || o3tl::make_unsigned( Index
) >= m_windows
.size() )
189 throw lang::IndexOutOfBoundsException();
190 return css::uno::Any( m_windows
[ Index
] ); // returns xspreadsheetdoc
194 virtual uno::Type SAL_CALL
getElementType( ) override
196 return cppu::UnoType
<sheet::XSpreadsheetDocument
>::get();
199 virtual sal_Bool SAL_CALL
hasElements( ) override
201 return ( !m_windows
.empty() );
205 virtual uno::Any SAL_CALL
getByName( const OUString
& aName
) override
207 NameIndexHash::const_iterator it
= namesToIndices
.find( aName
);
208 if ( it
== namesToIndices
.end() )
209 throw container::NoSuchElementException();
210 return css::uno::Any( m_windows
[ it
->second
] );
214 virtual uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) override
216 return comphelper::mapKeysToSequence( namesToIndices
);
219 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
221 NameIndexHash::const_iterator it
= namesToIndices
.find( aName
);
222 return (it
!= namesToIndices
.end());
229 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
) ) )
232 uno::Reference
< container::XEnumeration
>
233 ScVbaWindows::createEnumeration()
235 return new WindowEnumImpl( mxContext
, Application() );
239 ScVbaWindows::createCollectionObject( const css::uno::Any
& aSource
)
241 return ComponentToWindow( aSource
, mxContext
, Application() );
245 ScVbaWindows::getElementType()
247 return cppu::UnoType
<excel::XWindows
>::get();
251 ScVbaWindows::Arrange( ::sal_Int32
/*ArrangeStyle*/, const uno::Any
& /*ActiveWorkbook*/, const uno::Any
& /*SyncHorizontal*/, const uno::Any
& /*SyncVertical*/ )
253 //#TODO #FIXME see what can be done for an implementation here
257 ScVbaWindows::getServiceImplName()
259 return u
"ScVbaWindows"_ustr
;
262 css::uno::Sequence
<OUString
>
263 ScVbaWindows::getServiceNames()
265 static uno::Sequence
< OUString
> const sNames
267 u
"ooo.vba.excel.Windows"_ustr
272 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */