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