xref: /AOO41X/main/framework/source/helper/oframes.cxx (revision 6d739b60ff8f4ed2134ae1442e284f9da90334b4)
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! Ouer owner is dead.
126     LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::append()\nOuer 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! Ouer owner is dead.
153     LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::remove()\nOuer 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! Ouer owner is dead.
260     LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::queryFrames()\nOuer 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. Normaly 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 autor 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 ouer owner class, need a valid factory to instanciate new services and
432 // use the access to ouer 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