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 //_________________________________________________________________________________________________________________
28 // my own includes
29 //_________________________________________________________________________________________________________________
30 #include <helper/oframes.hxx>
31
32 #ifndef _FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_
33 #include <threadhelp/resetableguard.hxx>
34 #endif
35
36 //_________________________________________________________________________________________________________________
37 // interface includes
38 //_________________________________________________________________________________________________________________
39 #include <com/sun/star/frame/XDesktop.hpp>
40 #include <com/sun/star/frame/FrameSearchFlag.hpp>
41
42 //_________________________________________________________________________________________________________________
43 // includes of other projects
44 //_________________________________________________________________________________________________________________
45 #include <vcl/svapp.hxx>
46
47 //_________________________________________________________________________________________________________________
48 // namespace
49 //_________________________________________________________________________________________________________________
50
51 namespace framework{
52
53 using namespace ::com::sun::star::container ;
54 using namespace ::com::sun::star::frame ;
55 using namespace ::com::sun::star::lang ;
56 using namespace ::com::sun::star::uno ;
57 using namespace ::cppu ;
58 using namespace ::osl ;
59 using namespace ::rtl ;
60 using namespace ::std ;
61 using namespace ::vos ;
62
63 //_________________________________________________________________________________________________________________
64 // non exported const
65 //_________________________________________________________________________________________________________________
66
67 //_________________________________________________________________________________________________________________
68 // non exported definitions
69 //_________________________________________________________________________________________________________________
70
71 //_________________________________________________________________________________________________________________
72 // declarations
73 //_________________________________________________________________________________________________________________
74
75 //*****************************************************************************************************************
76 // constructor
77 //*****************************************************************************************************************
OFrames(const css::uno::Reference<XMultiServiceFactory> & xFactory,const css::uno::Reference<XFrame> & xOwner,FrameContainer * pFrameContainer)78 OFrames::OFrames( const css::uno::Reference< XMultiServiceFactory >& xFactory ,
79 const css::uno::Reference< XFrame >& xOwner ,
80 FrameContainer* pFrameContainer )
81 // Init baseclasses first
82 : ThreadHelpBase ( &Application::GetSolarMutex() )
83 // Init member
84 , m_xFactory ( xFactory )
85 , m_xOwner ( xOwner )
86 , m_pFrameContainer ( pFrameContainer )
87 , m_bRecursiveSearchProtection( sal_False )
88 {
89 // Safe impossible cases
90 // Method is not defined for ALL incoming parameters!
91 LOG_ASSERT( impldbg_checkParameter_OFramesCtor( xFactory, xOwner, pFrameContainer ), "OFrames::OFrames()\nInvalid parameter detected!\n" )
92 }
93
94 //*****************************************************************************************************************
95 // (proteced!) destructor
96 //*****************************************************************************************************************
~OFrames()97 OFrames::~OFrames()
98 {
99 // Reset instance, free memory ....
100 impl_resetObject();
101 }
102
103 //*****************************************************************************************************************
104 // XFrames
105 //*****************************************************************************************************************
append(const css::uno::Reference<XFrame> & xFrame)106 void SAL_CALL OFrames::append( const css::uno::Reference< XFrame >& xFrame ) throw( RuntimeException )
107 {
108 // Ready for multithreading
109 ResetableGuard aGuard( m_aLock );
110
111 // Safe impossible cases
112 // Method is not defined for ALL incoming parameters!
113 LOG_ASSERT( impldbg_checkParameter_append( xFrame ), "OFrames::append()\nInvalid parameter detected!\n" )
114
115 // Do the follow only, if owner instance valid!
116 // Lock owner for follow operations - make a "hard reference"!
117 css::uno::Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY );
118 if ( xOwner.is() == sal_True )
119 {
120 // Append frame to the end of the container ...
121 m_pFrameContainer->append( xFrame );
122 // Set owner of this instance as parent of the new frame in container!
123 xFrame->setCreator( xOwner );
124 }
125 // Else; Do nothing! Our owner is dead.
126 LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::append()\nOur owner is dead - you can't append any frames ...!\n" )
127 }
128
129 //*****************************************************************************************************************
130 // XFrames
131 //*****************************************************************************************************************
remove(const css::uno::Reference<XFrame> & xFrame)132 void SAL_CALL OFrames::remove( const css::uno::Reference< XFrame >& xFrame ) throw( RuntimeException )
133 {
134 // Ready for multithreading
135 ResetableGuard aGuard( m_aLock );
136
137 // Safe impossible cases
138 // Method is not defined for ALL incoming parameters!
139 LOG_ASSERT( impldbg_checkParameter_remove( xFrame ), "OFrames::remove()\nInvalid parameter detected!\n" )
140
141 // Do the follow only, if owner instance valid!
142 // Lock owner for follow operations - make a "hard reference"!
143 css::uno::Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY );
144 if ( xOwner.is() == sal_True )
145 {
146 // Search frame and remove it from container ...
147 m_pFrameContainer->remove( xFrame );
148 // Don't reset owner-property of removed frame!
149 // This must do the caller of this method himself.
150 // See documentation of interface XFrames for further informations.
151 }
152 // Else; Do nothing! Our owner is dead.
153 LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::remove()\nOur owner is dead - you can't remove any frames ...!\n" )
154 }
155
156 //*****************************************************************************************************************
157 // XFrames
158 //*****************************************************************************************************************
queryFrames(sal_Int32 nSearchFlags)159 Sequence< css::uno::Reference< XFrame > > SAL_CALL OFrames::queryFrames( sal_Int32 nSearchFlags ) throw( RuntimeException )
160 {
161 // Ready for multithreading
162 ResetableGuard aGuard( m_aLock );
163
164 // Safe impossible cases
165 // Method is not defined for ALL incoming parameters!
166 LOG_ASSERT( impldbg_checkParameter_queryFrames( nSearchFlags ), "OFrames::queryFrames()\nInvalid parameter detected!\n" )
167
168 // Set default return value. (empty sequence)
169 Sequence< css::uno::Reference< XFrame > > seqFrames;
170
171 // Do the follow only, if owner instance valid.
172 // Lock owner for follow operations - make a "hard reference"!
173 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
174 if ( xOwner.is() == sal_True )
175 {
176 // Work only, if search was not started here ...!
177 if( m_bRecursiveSearchProtection == sal_False )
178 {
179 // This class is a helper for services, which must implement XFrames.
180 // His parent and childs are MY parent and childs to.
181 // All searchflags are supported by this implementation!
182 // If some flags should not be supported - don't call me with this flags!!!
183
184 //_____________________________________________________________________________________________________________
185 // Search with AUTO-flag is not supported yet!
186 // We think about right implementation.
187 LOG_ASSERT( !(nSearchFlags & FrameSearchFlag::AUTO), "OFrames::queryFrames()\nSearch with AUTO-flag is not supported yet!\nWe think about right implementation.\n" )
188 // If searched for tasks ...
189 // Its not supported yet.
190 LOG_ASSERT( !(nSearchFlags & FrameSearchFlag::AUTO), "OFrames::queryFrames()\nSearch for tasks not supported yet!\n" )
191
192 //_____________________________________________________________________________________________________________
193 // Search for ALL and GLOBAL is superflous!
194 // We support all necessary flags, from which these two flags are derived.
195 // ALL = PARENT + SELF + CHILDREN + SIBLINGS
196 // GLOBAL = ALL + TASKS
197
198 //_____________________________________________________________________________________________________________
199 // Add parent to list ... if any exist!
200 if( nSearchFlags & FrameSearchFlag::PARENT )
201 {
202 css::uno::Reference< XFrame > xParent( xOwner->getCreator(), UNO_QUERY );
203 if( xParent.is() == sal_True )
204 {
205 Sequence< css::uno::Reference< XFrame > > seqParent( 1 );
206 seqParent[0] = xParent;
207 impl_appendSequence( seqFrames, seqParent );
208 }
209 }
210
211 //_____________________________________________________________________________________________________________
212 // Add owner to list if SELF is searched.
213 if( nSearchFlags & FrameSearchFlag::SELF )
214 {
215 Sequence< css::uno::Reference< XFrame > > seqSelf( 1 );
216 seqSelf[0] = xOwner;
217 impl_appendSequence( seqFrames, seqSelf );
218 }
219
220 //_____________________________________________________________________________________________________________
221 // Add SIBLINGS to list.
222 if( nSearchFlags & FrameSearchFlag::SIBLINGS )
223 {
224 // Else; start a new search.
225 // Protect this instance against recursive calls from parents.
226 m_bRecursiveSearchProtection = sal_True;
227 // Ask parent of my owner for frames and append results to return list.
228 css::uno::Reference< XFramesSupplier > xParent( xOwner->getCreator(), UNO_QUERY );
229 // If a parent exist ...
230 if ( xParent.is() == sal_True )
231 {
232 // ... ask him for right frames.
233 impl_appendSequence( seqFrames, xParent->getFrames()->queryFrames( nSearchFlags ) );
234 }
235 // We have all searched informations.
236 // Reset protection-mode.
237 m_bRecursiveSearchProtection = sal_False;
238 }
239
240 //_____________________________________________________________________________________________________________
241 // If searched for children, step over all elements in container and collect the informations.
242 if ( nSearchFlags & FrameSearchFlag::CHILDREN )
243 {
244 // Don't search for parents, siblings and self at childrens!
245 // These things are supported by this instance himself.
246 sal_Int32 nChildSearchFlags = FrameSearchFlag::SELF | FrameSearchFlag::CHILDREN;
247 // Step over all items of container and ask childrens for frames.
248 sal_uInt32 nCount = m_pFrameContainer->getCount();
249 for ( sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex )
250 {
251 // We don't must control this conversion.
252 // We have done this at append()!
253 css::uno::Reference< XFramesSupplier > xItem( (*m_pFrameContainer)[nIndex], UNO_QUERY );
254 impl_appendSequence( seqFrames, xItem->getFrames()->queryFrames( nChildSearchFlags ) );
255 }
256 }
257 }
258 }
259 // Else; Do nothing! Our owner is dead.
260 LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::queryFrames()\nOur owner is dead - you can't query for frames ...!\n" )
261
262 // Resturn result of this operation.
263 return seqFrames;
264 }
265
266 //*****************************************************************************************************************
267 // XIndexAccess
268 //*****************************************************************************************************************
getCount()269 sal_Int32 SAL_CALL OFrames::getCount() throw( RuntimeException )
270 {
271 // Ready for multithreading
272 ResetableGuard aGuard( m_aLock );
273
274 // Set default return value.
275 sal_Int32 nCount = 0;
276
277 // Do the follow only, if owner instance valid.
278 // Lock owner for follow operations - make a "hard reference"!
279 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
280 if ( xOwner.is() == sal_True )
281 {
282 // Set CURRENT size of container for return.
283 nCount = m_pFrameContainer->getCount();
284 }
285
286 // Return result.
287 return nCount;
288 }
289
290 //*****************************************************************************************************************
291 // XIndexAccess
292 //*****************************************************************************************************************
getByIndex(sal_Int32 nIndex)293 Any SAL_CALL OFrames::getByIndex( sal_Int32 nIndex ) throw( IndexOutOfBoundsException ,
294 WrappedTargetException ,
295 RuntimeException )
296 {
297 // Ready for multithreading
298 ResetableGuard aGuard( m_aLock );
299
300 sal_uInt32 nCount = m_pFrameContainer->getCount();
301 if ( nIndex < 0 || ( sal::static_int_cast< sal_uInt32 >( nIndex ) >= nCount ))
302 throw IndexOutOfBoundsException( OUString::createFromAscii( "OFrames::getByIndex - Index out of bounds" ),
303 (OWeakObject *)this );
304
305 // Set default return value.
306 Any aReturnValue;
307
308 // Do the follow only, if owner instance valid.
309 // Lock owner for follow operations - make a "hard reference"!
310 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
311 if ( xOwner.is() == sal_True )
312 {
313 // Get element form container.
314 // (If index not valid, FrameContainer return NULL!)
315 aReturnValue <<= (*m_pFrameContainer)[nIndex];
316 }
317
318 // Return result of this operation.
319 return aReturnValue;
320 }
321
322 //*****************************************************************************************************************
323 // XElementAccess
324 //*****************************************************************************************************************
getElementType()325 Type SAL_CALL OFrames::getElementType() throw( RuntimeException )
326 {
327 // This "container" support XFrame-interfaces only!
328 return ::getCppuType( (const css::uno::Reference< XFrame >*)NULL );
329 }
330
331 //*****************************************************************************************************************
332 // XElementAccess
333 //*****************************************************************************************************************
hasElements()334 sal_Bool SAL_CALL OFrames::hasElements() throw( RuntimeException )
335 {
336 // Ready for multithreading
337 ResetableGuard aGuard( m_aLock );
338
339 // Set default return value.
340 sal_Bool bHasElements = sal_False;
341 // Do the follow only, if owner instance valid.
342 // Lock owner for follow operations - make a "hard reference"!
343 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
344 if ( xOwner.is() == sal_True )
345 {
346 // If some elements exist ...
347 if ( m_pFrameContainer->getCount() > 0 )
348 {
349 // ... change this state value!
350 bHasElements = sal_True;
351 }
352 }
353 // Return result of this operation.
354 return bHasElements;
355 }
356
357 //*****************************************************************************************************************
358 // proteced method
359 //*****************************************************************************************************************
impl_resetObject()360 void OFrames::impl_resetObject()
361 {
362 // Attention:
363 // Write this for multiple calls - NOT AT THE SAME TIME - but for more then one call again)!
364 // It exist two ways to call this method. From destructor and from disposing().
365 // I can't say, which one is the first. Normally the disposing-call - but other way ....
366
367 // This instance can't work if the weakreference to owner is invalid!
368 // Destroy this to reset this object.
369 m_xOwner = WeakReference< XFrame >();
370 // Reset pointer to shared container to!
371 m_pFrameContainer = NULL;
372 }
373
374 //*****************************************************************************************************************
375 // private method
376 //*****************************************************************************************************************
impl_appendSequence(Sequence<css::uno::Reference<XFrame>> & seqDestination,const Sequence<css::uno::Reference<XFrame>> & seqSource)377 void OFrames::impl_appendSequence( Sequence< css::uno::Reference< XFrame > >& seqDestination ,
378 const Sequence< css::uno::Reference< XFrame > >& seqSource )
379 {
380 // Get some informations about the sequences.
381 sal_Int32 nSourceCount = seqSource.getLength();
382 sal_Int32 nDestinationCount = seqDestination.getLength();
383 const css::uno::Reference< XFrame >* pSourceAccess = seqSource.getConstArray();
384 css::uno::Reference< XFrame >* pDestinationAccess = seqDestination.getArray();
385
386 // Get memory for result list.
387 Sequence< css::uno::Reference< XFrame > > seqResult ( nSourceCount + nDestinationCount );
388 css::uno::Reference< XFrame >* pResultAccess = seqResult.getArray();
389 sal_Int32 nResultPosition = 0;
390
391 // Copy all items from first sequence.
392 for ( sal_Int32 nSourcePosition=0; nSourcePosition<nSourceCount; ++nSourcePosition )
393 {
394 pResultAccess[nResultPosition] = pSourceAccess[nSourcePosition];
395 ++nResultPosition;
396 }
397
398 // Don't manipulate nResultPosition between these two loops!
399 // Its the current position in the result list.
400
401 // Copy all items from second sequence.
402 for ( sal_Int32 nDestinationPosition=0; nDestinationPosition<nDestinationCount; ++nDestinationPosition )
403 {
404 pResultAccess[nResultPosition] = pDestinationAccess[nDestinationPosition];
405 ++nResultPosition;
406 }
407
408 // Return result of this operation.
409 seqDestination.realloc( 0 );
410 seqDestination = seqResult;
411 }
412
413 //_________________________________________________________________________________________________________________
414 // debug methods
415 //_________________________________________________________________________________________________________________
416
417 /*-----------------------------------------------------------------------------------------------------------------
418 The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
419 we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
420
421 ATTENTION
422
423 If you miss a test for one of this parameters, contact the author or add it himself !(?)
424 But ... look for right testing! See using of this methods!
425 -----------------------------------------------------------------------------------------------------------------*/
426
427 #ifdef ENABLE_ASSERTIONS
428
429 //*****************************************************************************************************************
430 // An instance of this class can only work with valid initialization.
431 // We share the mutex with our owner class, need a valid factory to instanciate new services and
432 // use the access to our owner for some operations.
impldbg_checkParameter_OFramesCtor(const css::uno::Reference<XMultiServiceFactory> & xFactory,const css::uno::Reference<XFrame> & xOwner,FrameContainer * pFrameContainer)433 sal_Bool OFrames::impldbg_checkParameter_OFramesCtor( const css::uno::Reference< XMultiServiceFactory >& xFactory ,
434 const css::uno::Reference< XFrame >& xOwner ,
435 FrameContainer* pFrameContainer )
436 {
437 // Set default return value.
438 sal_Bool bOK = sal_True;
439 // Check parameter.
440 if (
441 ( &xFactory == NULL ) ||
442 ( &xOwner == NULL ) ||
443 ( xFactory.is() == sal_False ) ||
444 ( xOwner.is() == sal_False ) ||
445 ( pFrameContainer == NULL )
446 )
447 {
448 bOK = sal_False ;
449 }
450 // Return result of check.
451 return bOK ;
452 }
453
454 //*****************************************************************************************************************
455 // Its only allowed to add valid references to container.
456 // AND - alle frames must support XFrames-interface!
impldbg_checkParameter_append(const css::uno::Reference<XFrame> & xFrame)457 sal_Bool OFrames::impldbg_checkParameter_append( const css::uno::Reference< XFrame >& xFrame )
458 {
459 // Set default return value.
460 sal_Bool bOK = sal_True;
461 // Check parameter.
462 if (
463 ( &xFrame == NULL ) ||
464 ( xFrame.is() == sal_False )
465 )
466 {
467 bOK = sal_False ;
468 }
469 // Return result of check.
470 return bOK ;
471 }
472
473 //*****************************************************************************************************************
474 // Its only allowed to add valid references to container...
475 // ... => You can only delete valid references!
impldbg_checkParameter_remove(const css::uno::Reference<XFrame> & xFrame)476 sal_Bool OFrames::impldbg_checkParameter_remove( const css::uno::Reference< XFrame >& xFrame )
477 {
478 // Set default return value.
479 sal_Bool bOK = sal_True;
480 // Check parameter.
481 if (
482 ( &xFrame == NULL ) ||
483 ( xFrame.is() == sal_False )
484 )
485 {
486 bOK = sal_False ;
487 }
488 // Return result of check.
489 return bOK ;
490 }
491
492 //*****************************************************************************************************************
493 // A search for frames must initiate with right flags.
494 // Some one are superflous and not supported yet. But here we control only the range of incoming parameter!
impldbg_checkParameter_queryFrames(sal_Int32 nSearchFlags)495 sal_Bool OFrames::impldbg_checkParameter_queryFrames( sal_Int32 nSearchFlags )
496 {
497 // Set default return value.
498 sal_Bool bOK = sal_True;
499 // Check parameter.
500 if (
501 ( nSearchFlags != FrameSearchFlag::AUTO ) &&
502 ( !( nSearchFlags & FrameSearchFlag::PARENT ) ) &&
503 ( !( nSearchFlags & FrameSearchFlag::SELF ) ) &&
504 ( !( nSearchFlags & FrameSearchFlag::CHILDREN ) ) &&
505 ( !( nSearchFlags & FrameSearchFlag::CREATE ) ) &&
506 ( !( nSearchFlags & FrameSearchFlag::SIBLINGS ) ) &&
507 ( !( nSearchFlags & FrameSearchFlag::TASKS ) ) &&
508 ( !( nSearchFlags & FrameSearchFlag::ALL ) ) &&
509 ( !( nSearchFlags & FrameSearchFlag::GLOBAL ) )
510 )
511 {
512 bOK = sal_False ;
513 }
514 // Return result of check.
515 return bOK ;
516 }
517
518 #endif // #ifdef ENABLE_ASSERTIONS
519
520 } // namespace framework
521