1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_framework.hxx"
26
27 #include <classes/rootactiontriggercontainer.hxx>
28 #include <classes/actiontriggercontainer.hxx>
29 #include <classes/actiontriggerpropertyset.hxx>
30 #include <classes/actiontriggerseparatorpropertyset.hxx>
31 #include <framework/actiontriggerhelper.hxx>
32 #include <threadhelp/resetableguard.hxx>
33 #include <osl/mutex.hxx>
34 #include <vcl/svapp.hxx>
35 #include <cppuhelper/typeprovider.hxx>
36
37
38 using namespace cppu;
39 using namespace com::sun::star::uno;
40 using namespace com::sun::star::lang;
41 using namespace com::sun::star::container;
42 using namespace com::sun::star::beans;
43
44
45 namespace framework
46 {
47
impl_getStaticIdentifier()48 static Sequence< sal_Int8 > impl_getStaticIdentifier()
49 {
50 static sal_uInt8 pGUID[16] = { 0x17, 0x0F, 0xA2, 0xC9, 0xCA, 0x50, 0x4A, 0xD3, 0xA6, 0x3B, 0x39, 0x99, 0xC5, 0x96, 0x43, 0x27 };
51 static ::com::sun::star::uno::Sequence< sal_Int8 > seqID((sal_Int8*)pGUID,16) ;
52 return seqID ;
53 }
54
55
RootActionTriggerContainer(const Menu * pMenu,const::rtl::OUString * pMenuIdentifier,const Reference<XMultiServiceFactory> & rServiceManager)56 RootActionTriggerContainer::RootActionTriggerContainer( const Menu* pMenu, const ::rtl::OUString* pMenuIdentifier, const Reference< XMultiServiceFactory >& rServiceManager ) :
57 PropertySetContainer( rServiceManager )
58 , m_bContainerCreated( sal_False )
59 , m_bContainerChanged( sal_False )
60 , m_bInContainerCreation( sal_False )
61 , m_pMenu( pMenu )
62 , m_pMenuIdentifier( pMenuIdentifier )
63 {
64 }
65
~RootActionTriggerContainer()66 RootActionTriggerContainer::~RootActionTriggerContainer()
67 {
68 }
69
GetUnoTunnelId() const70 Sequence< sal_Int8 > RootActionTriggerContainer::GetUnoTunnelId() const
71 {
72 return impl_getStaticIdentifier();
73 }
74
GetMenu()75 const Menu* RootActionTriggerContainer::GetMenu()
76 {
77 if ( !m_bContainerChanged )
78 return m_pMenu;
79 else
80 {
81 ResetableGuard aGuard( m_aLock );
82
83 Menu* pNewMenu = new PopupMenu;
84
85 ActionTriggerHelper::CreateMenuFromActionTriggerContainer( pNewMenu, this );
86 m_pMenu = pNewMenu;
87 m_bContainerChanged = sal_False;
88
89 return m_pMenu;
90 }
91 }
92
93
94 // XInterface
queryInterface(const Type & aType)95 Any SAL_CALL RootActionTriggerContainer::queryInterface( const Type& aType )
96 {
97 Any a = ::cppu::queryInterface(
98 aType ,
99 SAL_STATIC_CAST( XMultiServiceFactory* , this ),
100 SAL_STATIC_CAST( XServiceInfo* , this ),
101 SAL_STATIC_CAST( XUnoTunnel* , this ),
102 SAL_STATIC_CAST( XTypeProvider* , this ),
103 SAL_STATIC_CAST( XNamed* , this ));
104
105 if( a.hasValue() )
106 {
107 return a;
108 }
109
110 return PropertySetContainer::queryInterface( aType );
111 }
112
acquire()113 void SAL_CALL RootActionTriggerContainer::acquire() throw ()
114 {
115 PropertySetContainer::acquire();
116 }
117
release()118 void SAL_CALL RootActionTriggerContainer::release() throw ()
119 {
120 PropertySetContainer::release();
121 }
122
123 // XMultiServiceFactory
createInstance(const::rtl::OUString & aServiceSpecifier)124 Reference< XInterface > SAL_CALL RootActionTriggerContainer::createInstance( const ::rtl::OUString& aServiceSpecifier )
125 {
126 if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGER ))
127 return (OWeakObject *)( new ActionTriggerPropertySet( m_xServiceManager ));
128 else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
129 return (OWeakObject *)( new ActionTriggerContainer( m_xServiceManager ));
130 else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERSEPARATOR ))
131 return (OWeakObject *)( new ActionTriggerSeparatorPropertySet( m_xServiceManager ));
132 else
133 throw com::sun::star::uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown service specifier!" )), (OWeakObject *)this );
134 }
135
createInstanceWithArguments(const::rtl::OUString & ServiceSpecifier,const Sequence<Any> &)136 Reference< XInterface > SAL_CALL RootActionTriggerContainer::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/ )
137 {
138 return createInstance( ServiceSpecifier );
139 }
140
getAvailableServiceNames()141 Sequence< ::rtl::OUString > SAL_CALL RootActionTriggerContainer::getAvailableServiceNames()
142 {
143 Sequence< ::rtl::OUString > aSeq( 3 );
144
145 aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGER ));
146 aSeq[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
147 aSeq[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR ));
148
149 return aSeq;
150 }
151
152
153 // XIndexContainer
insertByIndex(sal_Int32 Index,const Any & Element)154 void SAL_CALL RootActionTriggerContainer::insertByIndex( sal_Int32 Index, const Any& Element )
155 {
156 ResetableGuard aGuard( m_aLock );
157
158 if ( !m_bContainerCreated )
159 FillContainer();
160
161 if ( !m_bInContainerCreation )
162 m_bContainerChanged = sal_True;
163 PropertySetContainer::insertByIndex( Index, Element );
164 }
165
removeByIndex(sal_Int32 Index)166 void SAL_CALL RootActionTriggerContainer::removeByIndex( sal_Int32 Index )
167 {
168 ResetableGuard aGuard( m_aLock );
169
170 if ( !m_bContainerCreated )
171 FillContainer();
172
173 if ( !m_bInContainerCreation )
174 m_bContainerChanged = sal_True;
175 PropertySetContainer::removeByIndex( Index );
176 }
177
178
179 // XIndexReplace
replaceByIndex(sal_Int32 Index,const Any & Element)180 void SAL_CALL RootActionTriggerContainer::replaceByIndex( sal_Int32 Index, const Any& Element )
181 {
182 ResetableGuard aGuard( m_aLock );
183
184 if ( !m_bContainerCreated )
185 FillContainer();
186
187 if ( !m_bInContainerCreation )
188 m_bContainerChanged = sal_True;
189 PropertySetContainer::replaceByIndex( Index, Element );
190 }
191
192
193 // XIndexAccess
getCount()194 sal_Int32 SAL_CALL RootActionTriggerContainer::getCount()
195 {
196 ResetableGuard aGuard( m_aLock );
197
198 if ( !m_bContainerCreated )
199 {
200 if ( m_pMenu )
201 {
202 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
203 return m_pMenu->GetItemCount();
204 }
205 else
206 return 0;
207 }
208 else
209 {
210 return PropertySetContainer::getCount();
211 }
212 }
213
getByIndex(sal_Int32 Index)214 Any SAL_CALL RootActionTriggerContainer::getByIndex( sal_Int32 Index )
215 {
216 ResetableGuard aGuard( m_aLock );
217
218 if ( !m_bContainerCreated )
219 FillContainer();
220
221 return PropertySetContainer::getByIndex( Index );
222 }
223
224
225 // XElementAccess
getElementType()226 Type SAL_CALL RootActionTriggerContainer::getElementType()
227 {
228 return ::getCppuType(( Reference< XPropertySet >*)0);
229 }
230
hasElements()231 sal_Bool SAL_CALL RootActionTriggerContainer::hasElements()
232 {
233 if ( m_pMenu )
234 {
235 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
236 return ( m_pMenu->GetItemCount() > 0 );
237 }
238
239 return sal_False;
240 }
241
242
243 // XServiceInfo
getImplementationName()244 ::rtl::OUString SAL_CALL RootActionTriggerContainer::getImplementationName()
245 {
246 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ROOTACTIONTRIGGERCONTAINER ));
247 }
248
supportsService(const::rtl::OUString & ServiceName)249 sal_Bool SAL_CALL RootActionTriggerContainer::supportsService( const ::rtl::OUString& ServiceName )
250 {
251 if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
252 return sal_True;
253
254 return sal_False;
255 }
256
getSupportedServiceNames()257 Sequence< ::rtl::OUString > SAL_CALL RootActionTriggerContainer::getSupportedServiceNames()
258 {
259 Sequence< ::rtl::OUString > seqServiceNames( 1 );
260
261 seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
262 return seqServiceNames;
263 }
264
265 // XUnoTunnel
getSomething(const Sequence<sal_Int8> & aIdentifier)266 sal_Int64 SAL_CALL RootActionTriggerContainer::getSomething( const Sequence< sal_Int8 >& aIdentifier )
267 {
268 if ( aIdentifier == impl_getStaticIdentifier() )
269 return reinterpret_cast< sal_Int64 >( this );
270 else
271 return 0;
272 }
273
274 // XTypeProvider
getTypes()275 Sequence< Type > SAL_CALL RootActionTriggerContainer::getTypes()
276 {
277 // Optimize this method !
278 // We initialize a static variable only one time. And we don't must use a mutex at every call!
279 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
280 static ::cppu::OTypeCollection* pTypeCollection = NULL ;
281
282 if ( pTypeCollection == NULL )
283 {
284 // Ready for multithreading; get global mutex for first call of this method only! see before
285 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
286
287 // Control these pointer again ... it can be, that another instance will be faster then these!
288 if ( pTypeCollection == NULL )
289 {
290 // Create a static typecollection ...
291 static ::cppu::OTypeCollection aTypeCollection(
292 ::getCppuType(( const Reference< XMultiServiceFactory >*)NULL ) ,
293 ::getCppuType(( const Reference< XIndexContainer >*)NULL ) ,
294 ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
295 ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ,
296 ::getCppuType(( const Reference< XUnoTunnel >*)NULL ) ,
297 ::getCppuType(( const Reference< XNamed >*)NULL )) ;
298
299 // ... and set his address to static pointer!
300 pTypeCollection = &aTypeCollection ;
301 }
302 }
303
304 return pTypeCollection->getTypes() ;
305 }
306
getImplementationId()307 Sequence< sal_Int8 > SAL_CALL RootActionTriggerContainer::getImplementationId()
308 {
309 // Create one Id for all instances of this class.
310 // Use ethernet address to do this! (sal_True)
311
312 // Optimize this method
313 // We initialize a static variable only one time. And we don't must use a mutex at every call!
314 // For the first call; pID is NULL - for the second call pID is different from NULL!
315 static ::cppu::OImplementationId* pID = NULL ;
316
317 if ( pID == NULL )
318 {
319 // Ready for multithreading; get global mutex for first call of this method only! see before
320 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
321
322 // Control these pointer again ... it can be, that another instance will be faster then these!
323 if ( pID == NULL )
324 {
325 // Create a new static ID ...
326 static ::cppu::OImplementationId aID( sal_False ) ;
327 // ... and set his address to static pointer!
328 pID = &aID ;
329 }
330 }
331
332 return pID->getImplementationId() ;
333 }
334
335 // private implementation helper
FillContainer()336 void RootActionTriggerContainer::FillContainer()
337 {
338 m_bContainerCreated = sal_True;
339 m_bInContainerCreation = sal_True;
340 Reference<XIndexContainer> xXIndexContainer( (OWeakObject *)this, UNO_QUERY );
341 ActionTriggerHelper::FillActionTriggerContainerFromMenu(
342 xXIndexContainer,
343 m_pMenu );
344 m_bInContainerCreation = sal_False;
345 }
getName()346 ::rtl::OUString RootActionTriggerContainer::getName()
347 {
348 ::rtl::OUString sRet;
349 if( m_pMenuIdentifier )
350 sRet = *m_pMenuIdentifier;
351 return sRet;
352 }
353
setName(const::rtl::OUString &)354 void RootActionTriggerContainer::setName( const ::rtl::OUString& )
355 {
356 throw RuntimeException();
357 }
358 }
359