xref: /trunk/main/framework/source/fwe/classes/rootactiontriggercontainer.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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