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 )
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 )
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 )
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 // Return result of this operation.
263 return seqFrames;
264 }
265
266 //*****************************************************************************************************************
267 // XIndexAccess
268 //*****************************************************************************************************************
getCount()269 sal_Int32 SAL_CALL OFrames::getCount()
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 )
294 {
295 // Ready for multithreading
296 ResetableGuard aGuard( m_aLock );
297
298 sal_uInt32 nCount = m_pFrameContainer->getCount();
299 if ( nIndex < 0 || ( sal::static_int_cast< sal_uInt32 >( nIndex ) >= nCount ))
300 throw IndexOutOfBoundsException( OUString::createFromAscii( "OFrames::getByIndex - Index out of bounds" ),
301 (OWeakObject *)this );
302
303 // Set default return value.
304 Any aReturnValue;
305
306 // Do the follow only, if owner instance valid.
307 // Lock owner for follow operations - make a "hard reference"!
308 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
309 if ( xOwner.is() == sal_True )
310 {
311 // Get element form container.
312 // (If index not valid, FrameContainer return NULL!)
313 aReturnValue <<= (*m_pFrameContainer)[nIndex];
314 }
315
316 // Return result of this operation.
317 return aReturnValue;
318 }
319
320 //*****************************************************************************************************************
321 // XElementAccess
322 //*****************************************************************************************************************
getElementType()323 Type SAL_CALL OFrames::getElementType()
324 {
325 // This "container" support XFrame-interfaces only!
326 return ::getCppuType( (const css::uno::Reference< XFrame >*)NULL );
327 }
328
329 //*****************************************************************************************************************
330 // XElementAccess
331 //*****************************************************************************************************************
hasElements()332 sal_Bool SAL_CALL OFrames::hasElements()
333 {
334 // Ready for multithreading
335 ResetableGuard aGuard( m_aLock );
336
337 // Set default return value.
338 sal_Bool bHasElements = sal_False;
339 // Do the follow only, if owner instance valid.
340 // Lock owner for follow operations - make a "hard reference"!
341 css::uno::Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY );
342 if ( xOwner.is() == sal_True )
343 {
344 // If some elements exist ...
345 if ( m_pFrameContainer->getCount() > 0 )
346 {
347 // ... change this state value!
348 bHasElements = sal_True;
349 }
350 }
351 // Return result of this operation.
352 return bHasElements;
353 }
354
355 //*****************************************************************************************************************
356 // proteced method
357 //*****************************************************************************************************************
impl_resetObject()358 void OFrames::impl_resetObject()
359 {
360 // Attention:
361 // Write this for multiple calls - NOT AT THE SAME TIME - but for more then one call again)!
362 // It exist two ways to call this method. From destructor and from disposing().
363 // I can't say, which one is the first. Normally the disposing-call - but other way ....
364
365 // This instance can't work if the weakreference to owner is invalid!
366 // Destroy this to reset this object.
367 m_xOwner = WeakReference< XFrame >();
368 // Reset pointer to shared container to!
369 m_pFrameContainer = NULL;
370 }
371
372 //*****************************************************************************************************************
373 // private method
374 //*****************************************************************************************************************
impl_appendSequence(Sequence<css::uno::Reference<XFrame>> & seqDestination,const Sequence<css::uno::Reference<XFrame>> & seqSource)375 void OFrames::impl_appendSequence( Sequence< css::uno::Reference< XFrame > >& seqDestination ,
376 const Sequence< css::uno::Reference< XFrame > >& seqSource )
377 {
378 // Get some informations about the sequences.
379 sal_Int32 nSourceCount = seqSource.getLength();
380 sal_Int32 nDestinationCount = seqDestination.getLength();
381 const css::uno::Reference< XFrame >* pSourceAccess = seqSource.getConstArray();
382 css::uno::Reference< XFrame >* pDestinationAccess = seqDestination.getArray();
383
384 // Get memory for result list.
385 Sequence< css::uno::Reference< XFrame > > seqResult ( nSourceCount + nDestinationCount );
386 css::uno::Reference< XFrame >* pResultAccess = seqResult.getArray();
387 sal_Int32 nResultPosition = 0;
388
389 // Copy all items from first sequence.
390 for ( sal_Int32 nSourcePosition=0; nSourcePosition<nSourceCount; ++nSourcePosition )
391 {
392 pResultAccess[nResultPosition] = pSourceAccess[nSourcePosition];
393 ++nResultPosition;
394 }
395
396 // Don't manipulate nResultPosition between these two loops!
397 // Its the current position in the result list.
398
399 // Copy all items from second sequence.
400 for ( sal_Int32 nDestinationPosition=0; nDestinationPosition<nDestinationCount; ++nDestinationPosition )
401 {
402 pResultAccess[nResultPosition] = pDestinationAccess[nDestinationPosition];
403 ++nResultPosition;
404 }
405
406 // Return result of this operation.
407 seqDestination.realloc( 0 );
408 seqDestination = seqResult;
409 }
410
411 //_________________________________________________________________________________________________________________
412 // debug methods
413 //_________________________________________________________________________________________________________________
414
415 /*-----------------------------------------------------------------------------------------------------------------
416 The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
417 we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
418
419 ATTENTION
420
421 If you miss a test for one of this parameters, contact the author or add it himself !(?)
422 But ... look for right testing! See using of this methods!
423 -----------------------------------------------------------------------------------------------------------------*/
424
425 #ifdef ENABLE_ASSERTIONS
426
427 //*****************************************************************************************************************
428 // An instance of this class can only work with valid initialization.
429 // We share the mutex with our owner class, need a valid factory to instantiate new services and
430 // 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)431 sal_Bool OFrames::impldbg_checkParameter_OFramesCtor( const css::uno::Reference< XMultiServiceFactory >& xFactory ,
432 const css::uno::Reference< XFrame >& xOwner ,
433 FrameContainer* pFrameContainer )
434 {
435 // Set default return value.
436 sal_Bool bOK = sal_True;
437 // Check parameter.
438 if (
439 ( &xFactory == NULL ) ||
440 ( &xOwner == NULL ) ||
441 ( xFactory.is() == sal_False ) ||
442 ( xOwner.is() == sal_False ) ||
443 ( pFrameContainer == NULL )
444 )
445 {
446 bOK = sal_False ;
447 }
448 // Return result of check.
449 return bOK ;
450 }
451
452 //*****************************************************************************************************************
453 // Its only allowed to add valid references to container.
454 // AND - alle frames must support XFrames-interface!
impldbg_checkParameter_append(const css::uno::Reference<XFrame> & xFrame)455 sal_Bool OFrames::impldbg_checkParameter_append( const css::uno::Reference< XFrame >& xFrame )
456 {
457 // Set default return value.
458 sal_Bool bOK = sal_True;
459 // Check parameter.
460 if (
461 ( &xFrame == NULL ) ||
462 ( xFrame.is() == sal_False )
463 )
464 {
465 bOK = sal_False ;
466 }
467 // Return result of check.
468 return bOK ;
469 }
470
471 //*****************************************************************************************************************
472 // Its only allowed to add valid references to container...
473 // ... => You can only delete valid references!
impldbg_checkParameter_remove(const css::uno::Reference<XFrame> & xFrame)474 sal_Bool OFrames::impldbg_checkParameter_remove( const css::uno::Reference< XFrame >& xFrame )
475 {
476 // Set default return value.
477 sal_Bool bOK = sal_True;
478 // Check parameter.
479 if (
480 ( &xFrame == NULL ) ||
481 ( xFrame.is() == sal_False )
482 )
483 {
484 bOK = sal_False ;
485 }
486 // Return result of check.
487 return bOK ;
488 }
489
490 //*****************************************************************************************************************
491 // A search for frames must initiate with right flags.
492 // Some one are superflous and not supported yet. But here we control only the range of incoming parameter!
impldbg_checkParameter_queryFrames(sal_Int32 nSearchFlags)493 sal_Bool OFrames::impldbg_checkParameter_queryFrames( sal_Int32 nSearchFlags )
494 {
495 // Set default return value.
496 sal_Bool bOK = sal_True;
497 // Check parameter.
498 if (
499 ( nSearchFlags != FrameSearchFlag::AUTO ) &&
500 ( !( nSearchFlags & FrameSearchFlag::PARENT ) ) &&
501 ( !( nSearchFlags & FrameSearchFlag::SELF ) ) &&
502 ( !( nSearchFlags & FrameSearchFlag::CHILDREN ) ) &&
503 ( !( nSearchFlags & FrameSearchFlag::CREATE ) ) &&
504 ( !( nSearchFlags & FrameSearchFlag::SIBLINGS ) ) &&
505 ( !( nSearchFlags & FrameSearchFlag::TASKS ) ) &&
506 ( !( nSearchFlags & FrameSearchFlag::ALL ) ) &&
507 ( !( nSearchFlags & FrameSearchFlag::GLOBAL ) )
508 )
509 {
510 bOK = sal_False ;
511 }
512 // Return result of check.
513 return bOK ;
514 }
515
516 #endif // #ifdef ENABLE_ASSERTIONS
517
518 } // namespace framework
519