xref: /trunk/main/framework/source/helper/oframes.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 //_________________________________________________________________________________________________________________
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