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