1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 //_________________________________________________________________________________________________________________
32 //	my own includes
33 //_________________________________________________________________________________________________________________
34 
35 #ifndef __FRAMEWORK_FRAMECONTAINER_HXX_
36 #include <classes/framecontainer.hxx>
37 #endif
38 #include <threadhelp/writeguard.hxx>
39 #include <threadhelp/readguard.hxx>
40 
41 #ifndef __FRAMEWORK_COMMANDS_HXX_
42 #include <commands.h>
43 #endif
44 
45 //_________________________________________________________________________________________________________________
46 //	interface includes
47 //_________________________________________________________________________________________________________________
48 
49 #ifndef _COM_SUN_STAR_FRAME_FRAMESEARCH_FLAG_HPP_
50 #include <com/sun/star/frame/FrameSearchFlag.hpp>
51 #endif
52 
53 //_________________________________________________________________________________________________________________
54 //	includes of other projects
55 //_________________________________________________________________________________________________________________
56 #include <vcl/svapp.hxx>
57 
58 //_________________________________________________________________________________________________________________
59 //	namespace
60 //_________________________________________________________________________________________________________________
61 
62 namespace framework{
63 
64 //_________________________________________________________________________________________________________________
65 //	non exported const
66 //_________________________________________________________________________________________________________________
67 
68 //_________________________________________________________________________________________________________________
69 //	non exported definitions
70 //_________________________________________________________________________________________________________________
71 
72 //_________________________________________________________________________________________________________________
73 //	declarations
74 //_________________________________________________________________________________________________________________
75 
76 /**-***************************************************************************************************************
77     @short      initialize an empty container
78     @descr      The container will be empty then - special features (e.g. the async quit mechanism) are disabled.
79 
80     @threadsafe not neccessary - its not a singleton
81     @modified   01.07.2002 14:42,as96863
82  *****************************************************************************************************************/
83 FrameContainer::FrameContainer()
84         // initialize base classes first.
85         // Order is neccessary for right initilization of his and OUR member ... m_aLock
86         : ThreadHelpBase ( &Application::GetSolarMutex()                  )
87 /*DEPRECATEME
88         , m_bAsyncQuit   ( sal_False                                      ) // default must be "disabled"!
89         , m_aAsyncCall   ( LINK( this, FrameContainer, implts_asyncQuit ) )
90 */
91 {
92 }
93 
94 /**-***************************************************************************************************************
95     @short      deinitialize may a filled container
96     @descr      Special features (if the currently are running) will be dsiabled and we free all used other ressources.
97 
98     @threadsafe not neccessary - its not a singleton
99     @modified   01.07.2002 14:43,as96863
100  *****************************************************************************************************************/
101 FrameContainer::~FrameContainer()
102 {
103 	// Don't forget to free memory!
104     m_aContainer.clear();
105     m_xActiveFrame.clear();
106 }
107 
108 /**-***************************************************************************************************************
109     @short      append a new frame to the container
110     @descr      We accept the incoming frame only, if it is a valid reference and dosnt exist already.
111 
112     @param      xFrame
113                     frame, which should be added to this container
114                     Must be a valid reference.
115 
116     @threadsafe yes
117     @modified   01.07.2002 14:44,as96863
118  *****************************************************************************************************************/
119 void FrameContainer::append( const css::uno::Reference< css::frame::XFrame >& xFrame )
120 {
121     if (xFrame.is() && ! exist(xFrame))
122     {
123         /* SAFE { */
124         WriteGuard aWriteLock( m_aLock );
125         m_aContainer.push_back( xFrame );
126         aWriteLock.unlock();
127         /* } SAFE */
128     }
129 }
130 
131 /**-***************************************************************************************************************
132     @short      remove a frame from the container
133     @descr      In case we remove the last frame and our internal special feature (the async quit mechanism)
134                 was enabled by the desktop instance, we start it.
135 
136     @param      xFrame
137                     frame, which should be deleted from this container
138                     Must be a valid reference.
139 
140     @threadsafe yes
141     @modified   01.07.2002 14:52,as96863
142  *****************************************************************************************************************/
143 void FrameContainer::remove( const css::uno::Reference< css::frame::XFrame >& xFrame )
144 {
145     /* SAFE { */
146     // write lock neccessary for follwing erase()!
147     WriteGuard aWriteLock( m_aLock );
148 
149     TFrameIterator aSearchedItem = ::std::find( m_aContainer.begin(), m_aContainer.end(), xFrame );
150     if (aSearchedItem!=m_aContainer.end())
151     {
152         m_aContainer.erase( aSearchedItem );
153 
154         // If removed frame was the current active frame - reset state variable.
155         if (m_xActiveFrame==xFrame)
156             m_xActiveFrame = css::uno::Reference< css::frame::XFrame >();
157 
158         // We don't need the write lock any longer ...
159         // downgrade to read access.
160         aWriteLock.downgrade();
161 /*DEPRECATEME
162         // If last frame was removed and special quit mode is enabled by the desktop
163         // we must terminate the application by using this asynchronous callback!
164         if (m_aContainer.size()<1 && m_bAsyncQuit)
165             m_aAsyncCall.Post(0);
166 */
167     }
168 
169     aWriteLock.unlock();
170     // } SAFE
171 }
172 
173 /**-***************************************************************************************************************
174     @short      check if the given frame currently exist inside the container
175     @descr      -
176 
177     @param      xFrame
178                     reference to the queried frame
179 
180     @return     <TRUE/> if frame is oart of this container
181                 <FALSE/> otherwhise
182 
183     @threadsafe yes
184     @modified   01.07.2002 14:55,as96863
185  *****************************************************************************************************************/
186 sal_Bool FrameContainer::exist( const css::uno::Reference< css::frame::XFrame >& xFrame ) const
187 {
188     /* SAFE { */
189     ReadGuard aReadLock( m_aLock );
190     return( ::std::find( m_aContainer.begin(), m_aContainer.end(), xFrame ) != m_aContainer.end() );
191     /* } SAFE */
192 }
193 
194 /**-***************************************************************************************************************
195     @short      delete all existing items of the container
196     @descr      -
197 
198     @threadsafe yes
199     @modified   01.07.2002 15:00,as96863
200  *****************************************************************************************************************/
201 void FrameContainer::clear()
202 {
203     // SAFE {
204     WriteGuard aWriteLock( m_aLock );
205 
206 	// Clear the container ...
207     m_aContainer.clear();
208 	// ... and don't forget to reset the active frame.
209 	// Its an reference to a valid container-item.
210 	// But no container item => no active frame!
211     m_xActiveFrame = css::uno::Reference< css::frame::XFrame >();
212 /*DEPRECATEME
213     // If special quit mode is used - we must terminate the desktop.
214 	// He is the owner of this container and can't work without any visible tasks/frames!
215     if (m_bAsyncQuit)
216         m_aAsyncCall.Post(0);
217 */
218 
219     aWriteLock.unlock();
220     // } SAFE
221 }
222 
223 /**-***************************************************************************************************************
224     @short      returns count of all current existing frames
225     @descr      -
226 
227     @deprecated This value can't be guaranteed for multithreading environments.
228                 So it will be marked as deprecated and should be replaced by "getAllElements()".
229 
230     @return     the count of existing container items
231 
232     @threadsafe yes
233     @modified   01.07.2002 15:00,as96863
234  *****************************************************************************************************************/
235 sal_uInt32 FrameContainer::getCount() const
236 {
237     /* SAFE { */
238     ReadGuard aReadLock( m_aLock );
239     return( (sal_uInt32)m_aContainer.size() );
240     /* } SAFE */
241 }
242 
243 /**-***************************************************************************************************************
244     @short      returns one item of this container
245     @descr      -
246 
247     @deprecated This value can't be guaranteed for multithreading environments.
248                 So it will be marked as deprecated and should be replaced by "getAllElements()".
249 
250     @param      nIndex
251                     a valud between 0 and (getCount()-1) to adress one container item
252 
253     @return     a reference to a frame inside the container, which match with given index
254 
255     @threadsafe yes
256     @modified   01.07.2002 15:03,as96863
257  *****************************************************************************************************************/
258 css::uno::Reference< css::frame::XFrame > FrameContainer::operator[]( sal_uInt32 nIndex ) const
259 {
260 
261     css::uno::Reference< css::frame::XFrame > xFrame;
262     try
263     {
264         // Get element form container WITH automatic test of ranges!
265         // If index not valid, a out_of_range exception is thrown.
266         /* SAFE { */
267         ReadGuard aReadLock( m_aLock );
268         xFrame = m_aContainer.at( nIndex );
269         aReadLock.unlock();
270         /* } SAFE */
271     }
272     catch( std::out_of_range& )
273     {
274         // The index is not valid for current container-content - we must handle this case!
275         // We can return the default value ...
276         LOG_EXCEPTION( "FrameContainer::operator[]", "Exception catched ...", DECLARE_ASCII("::std::out_of_range") )
277     }
278 	return xFrame;
279 }
280 
281 /**-***************************************************************************************************************
282     @short      returns a snapshot of all currently existing frames inside this container
283     @descr      Should be used to replace the deprecated functions getCount()/operator[]!
284 
285     @return     a list of all frame refrences inside this container
286 
287     @threadsafe yes
288     @modified   01.07.2002 15:09,as96863
289  *****************************************************************************************************************/
290 css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > FrameContainer::getAllElements() const
291 {
292     /* SAFE { */
293     ReadGuard aReadLock( m_aLock );
294 
295     sal_Int32                                                       nPosition = 0;
296     css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > lElements ( (sal_uInt32)m_aContainer.size() );
297     for (TConstFrameIterator pItem=m_aContainer.begin(); pItem!=m_aContainer.end(); ++pItem)
298         lElements[nPosition++] = *pItem;
299 
300     aReadLock.unlock();
301     /* } SAFE */
302 
303 	return lElements;
304 }
305 
306 /**-***************************************************************************************************************
307     @short      set the given frame as  the new active one inside this container
308     @descr      We accept this frame only, if it's already a part of this container.
309 
310     @param      xFrame
311                     reference to the new active frame
312                     Must be a valid reference and already part of this container.
313 
314     @threadsafe yes
315     @modified   01.07.2002 15:11,as96863
316  *****************************************************************************************************************/
317 void FrameContainer::setActive( const css::uno::Reference< css::frame::XFrame >& xFrame )
318 {
319     if ( !xFrame.is() || exist(xFrame) )
320     {
321         /* SAFE { */
322         WriteGuard aWriteLock( m_aLock );
323         m_xActiveFrame = xFrame;
324         aWriteLock.unlock();
325         /* } SAFE */
326     }
327 }
328 
329 /**-***************************************************************************************************************
330     @short      return sthe current active frame of this container
331     @descr      Value can be null in case the frame was removed from the container and nobody
332                 from outside decide which of all others should be the new one ...
333 
334     @return     a reference to the current active frame
335                 Value can be NULL!
336 
337     @threadsafe yes
338     @modified   01.07.2002 15:11,as96863
339  *****************************************************************************************************************/
340 css::uno::Reference< css::frame::XFrame > FrameContainer::getActive() const
341 {
342     /* SAFE { */
343     ReadGuard aReadLock( m_aLock );
344     return m_xActiveFrame;
345     /* } SAFE */
346 }
347 
348 /**-***************************************************************************************************************
349     @short      implements a simple search based on current container items
350     @descr      It can be used for findFrame() and implements a deep down search.
351 
352     @param      sName
353                     target name, which is searched
354 
355     @return     reference to the found frame or NULL if not.
356 
357     @threadsafe yes
358     @modified   01.07.2002 15:22,as96863
359  *****************************************************************************************************************/
360 css::uno::Reference< css::frame::XFrame > FrameContainer::searchOnAllChildrens( const ::rtl::OUString& sName ) const
361 {
362     /* SAFE { */
363     ReadGuard aReadLock( m_aLock );
364 
365     // Step over all child frames. But if direct child isn't the right one search on his children first - before
366     // you go to next direct child of this container!
367     css::uno::Reference< css::frame::XFrame > xSearchedFrame;
368     for( TConstFrameIterator pIterator=m_aContainer.begin(); pIterator!=m_aContainer.end(); ++pIterator )
369     {
370         if ((*pIterator)->getName()==sName)
371         {
372             xSearchedFrame = *pIterator;
373             break;
374         }
375         else
376         {
377             xSearchedFrame = (*pIterator)->findFrame( sName, css::frame::FrameSearchFlag::CHILDREN );
378             if (xSearchedFrame.is())
379                 break;
380         }
381     }
382     aReadLock.unlock();
383     /* } SAFE */
384 	return xSearchedFrame;
385 }
386 
387 /**-***************************************************************************************************************
388     @short      implements a simple search based on current container items
389     @descr      It can be used for findFrame() and search on members of this container only!
390 
391     @param      sName
392                     target name, which is searched
393 
394     @return     reference to the found frame or NULL if not.
395 
396     @threadsafe yes
397     @modified   01.07.2002 15:22,as96863
398  *****************************************************************************************************************/
399 css::uno::Reference< css::frame::XFrame > FrameContainer::searchOnDirectChildrens( const ::rtl::OUString& sName ) const
400 {
401     /* SAFE { */
402     ReadGuard aReadLock( m_aLock );
403 
404     css::uno::Reference< css::frame::XFrame > xSearchedFrame;
405     for( TConstFrameIterator pIterator=m_aContainer.begin(); pIterator!=m_aContainer.end(); ++pIterator )
406     {
407         if ((*pIterator)->getName()==sName)
408         {
409             xSearchedFrame = *pIterator;
410             break;
411         }
412     }
413     aReadLock.unlock();
414     /* } SAFE */
415 	return xSearchedFrame;
416 }
417 
418 } //  namespace framework
419