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