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