xref: /trunk/main/framework/source/services/frame.cxx (revision 478881a5)
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 <services/frame.hxx>
31 #include <dispatch/dispatchprovider.hxx>
32 
33 #ifndef __FRAMEWORK_DISPATCH_INTERCEPTIONHELPER_HXX_
34 #include <dispatch/interceptionhelper.hxx>
35 #endif
36 #include <dispatch/closedispatcher.hxx>
37 #include <dispatch/windowcommanddispatch.hxx>
38 #include <loadenv/loadenv.hxx>
39 #include <helper/oframes.hxx>
40 #include <helper/statusindicatorfactory.hxx>
41 #include <framework/titlehelper.hxx>
42 #include <classes/droptargetlistener.hxx>
43 #include <classes/taskcreator.hxx>
44 #include <loadenv/targethelper.hxx>
45 #include <framework/framelistanalyzer.hxx>
46 #include <helper/dockingareadefaultacceptor.hxx>
47 #include <dispatch/dispatchinformationprovider.hxx>
48 #include <threadhelp/transactionguard.hxx>
49 #include <pattern/window.hxx>
50 #include <services.h>
51 #include <properties.h>
52 
53 //_________________________________________________________________________________________________________________
54 //	interface includes
55 //_________________________________________________________________________________________________________________
56 #include <com/sun/star/lang/XInitialization.hpp>
57 #include <com/sun/star/lang/DisposedException.hpp>
58 #include <com/sun/star/task/XJobExecutor.hpp>
59 #include <com/sun/star/util/XURLTransformer.hpp>
60 #include <com/sun/star/util/XCloseable.hpp>
61 #include <com/sun/star/awt/XDevice.hpp>
62 #include <com/sun/star/awt/XTopWindow.hpp>
63 #include <com/sun/star/frame/XDesktop.hpp>
64 #include <com/sun/star/awt/PosSize.hpp>
65 #include <com/sun/star/frame/FrameSearchFlag.hpp>
66 #include <com/sun/star/awt/XWindowPeer.hpp>
67 #include <com/sun/star/awt/XVclWindowPeer.hpp>
68 #include <com/sun/star/task/XStatusIndicatorSupplier.hpp>
69 #include <com/sun/star/beans/PropertyAttribute.hpp>
70 #include <com/sun/star/beans/PropertyValue.hpp>
71 #include <com/sun/star/beans/XPropertySet.hpp>
72 #include <com/sun/star/frame/XModel.hpp>
73 #include <com/sun/star/awt/XDataTransferProviderAccess.hpp>
74 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
75 #include <com/sun/star/awt/WindowAttribute.hpp>
76 #include <com/sun/star/container/XIndexAccess.hpp>
77 #include <com/sun/star/beans/XMaterialHolder.hpp>
78 
79 #ifndef _COM_SUN_STAR_FRAME_XTITLECHANGEBROADCASTER_HPP_
80 #include <com/sun/star/frame/XTitleChangeBroadcaster.hpp>
81 #endif
82 
83 //_________________________________________________________________________________________________________________
84 //	includes of other projects
85 //_________________________________________________________________________________________________________________
86 #include <comphelper/sequenceashashmap.hxx>
87 #include <cppuhelper/queryinterface.hxx>
88 #include <cppuhelper/typeprovider.hxx>
89 #include <cppuhelper/factory.hxx>
90 #include <cppuhelper/proptypehlp.hxx>
91 #include <rtl/ustrbuf.hxx>
92 #include <vcl/window.hxx>
93 #include <vcl/wrkwin.hxx>
94 #include <vcl/svapp.hxx>
95 
96 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
97 #include <toolkit/helper/vclunohelper.hxx>
98 #endif
99 #include <toolkit/awt/vclxwindow.hxx>
100 #include <comphelper/processfactory.hxx>
101 #include <unotools/moduleoptions.hxx>
102 #include <tools/diagnose_ex.h>
103 
104 #ifdef ENABLE_ASSERTIONS
105 	#ifndef _RTL_STRBUF_HXX_
106 	#include <rtl/strbuf.hxx>
107 	#endif
108 #endif
109 
110 #include <vcl/menu.hxx>
111 
112 //_________________________________________________________________________________________________________________
113 //	namespace
114 //_________________________________________________________________________________________________________________
115 
116 namespace framework{
117 
118 //_________________________________________________________________________________________________________________
119 //	non exported const
120 //_________________________________________________________________________________________________________________
121 
122 //_________________________________________________________________________________________________________________
123 //	non exported definitions
124 //_________________________________________________________________________________________________________________
125 
126 css::uno::WeakReference< css::frame::XFrame > Frame::m_xCloserFrame = css::uno::WeakReference< css::frame::XFrame >();
127 
128 //_________________________________________________________________________________________________________________
129 //	declarations
130 //_________________________________________________________________________________________________________________
131 
132 //*****************************************************************************************************************
133 //	XInterface, XTypeProvider, XServiceInfo
134 //*****************************************************************************************************************
DEFINE_XINTERFACE_21(Frame,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XServiceInfo),DIRECT_INTERFACE (css::frame::XFramesSupplier),DIRECT_INTERFACE (css::frame::XFrame),DIRECT_INTERFACE (css::lang::XComponent),DIRECT_INTERFACE (css::task::XStatusIndicatorFactory),DIRECT_INTERFACE (css::frame::XDispatchProvider),DIRECT_INTERFACE (css::frame::XDispatchInformationProvider),DIRECT_INTERFACE (css::frame::XDispatchProviderInterception),DIRECT_INTERFACE (css::beans::XPropertySet),DIRECT_INTERFACE (css::beans::XPropertySetInfo),DIRECT_INTERFACE (css::awt::XWindowListener),DIRECT_INTERFACE (css::awt::XTopWindowListener),DIRECT_INTERFACE (css::awt::XFocusListener),DERIVED_INTERFACE (css::lang::XEventListener,css::awt::XWindowListener),DIRECT_INTERFACE (css::document::XActionLockable),DIRECT_INTERFACE (css::util::XCloseable),DIRECT_INTERFACE (css::util::XCloseBroadcaster),DIRECT_INTERFACE (css::frame::XComponentLoader),DIRECT_INTERFACE (css::frame::XTitle),DIRECT_INTERFACE (css::frame::XTitleChangeBroadcaster))135 DEFINE_XINTERFACE_21                (   Frame                                                                   ,
136 										OWeakObject																,
137 										DIRECT_INTERFACE(css::lang::XTypeProvider								),
138 										DIRECT_INTERFACE(css::lang::XServiceInfo								),
139 										DIRECT_INTERFACE(css::frame::XFramesSupplier							),
140 										DIRECT_INTERFACE(css::frame::XFrame										),
141 										DIRECT_INTERFACE(css::lang::XComponent									),
142 										DIRECT_INTERFACE(css::task::XStatusIndicatorFactory						),
143 										DIRECT_INTERFACE(css::frame::XDispatchProvider							),
144 										DIRECT_INTERFACE(css::frame::XDispatchInformationProvider				),
145 										DIRECT_INTERFACE(css::frame::XDispatchProviderInterception				),
146 										DIRECT_INTERFACE(css::beans::XPropertySet								),
147 										DIRECT_INTERFACE(css::beans::XPropertySetInfo   						),
148 										DIRECT_INTERFACE(css::awt::XWindowListener								),
149 										DIRECT_INTERFACE(css::awt::XTopWindowListener							),
150 										DIRECT_INTERFACE(css::awt::XFocusListener								),
151 										DERIVED_INTERFACE(css::lang::XEventListener, css::awt::XWindowListener	),
152                                         DIRECT_INTERFACE(css::document::XActionLockable                         ),
153                                         DIRECT_INTERFACE(css::util::XCloseable                                  ),
154                                         DIRECT_INTERFACE(css::util::XCloseBroadcaster                           ),
155                                         DIRECT_INTERFACE(css::frame::XComponentLoader                           ),
156                                         DIRECT_INTERFACE(css::frame::XTitle                                     ),
157                                         DIRECT_INTERFACE(css::frame::XTitleChangeBroadcaster                    )
158 									)
159 
160 DEFINE_XTYPEPROVIDER_20             (   Frame                                                                   ,
161 										css::lang::XTypeProvider												,
162 										css::lang::XServiceInfo													,
163 										css::frame::XFramesSupplier												,
164 										css::frame::XFrame														,
165 										css::lang::XComponent													,
166 										css::task::XStatusIndicatorFactory										,
167 										css::beans::XPropertySet												,
168 										css::beans::XPropertySetInfo											,
169 										css::frame::XDispatchProvider											,
170 										css::frame::XDispatchInformationProvider								,
171 										css::frame::XDispatchProviderInterception								,
172 										css::awt::XWindowListener								 				,
173 										css::awt::XTopWindowListener											,
174 										css::awt::XFocusListener												,
175                                         css::lang::XEventListener                                               ,
176                                         css::util::XCloseable                                                   ,
177                                         css::util::XCloseBroadcaster                                            ,
178                                         css::frame::XComponentLoader                                            ,
179                                         css::frame::XTitle                                                      ,
180                                         css::frame::XTitleChangeBroadcaster
181 									)
182 
183 DEFINE_XSERVICEINFO_MULTISERVICE	(	Frame																	,
184                                         ::cppu::OWeakObject                                                     ,
185 										SERVICENAME_FRAME														,
186 										IMPLEMENTATIONNAME_FRAME
187 									)
188 
189 DEFINE_INIT_SERVICE                 (   Frame,
190                                         {
191                                             /*Attention
192                                                 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
193                                                 to create a new instance of this class by our own supported service factory.
194                                                 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
195                                             */
196                                             css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY_THROW);
197 
198                                             //-------------------------------------------------------------------------------------------------------------
199                                             // Initialize a new dispatchhelper-object to handle dispatches.
200                                             // We use these helper as slave for our interceptor helper ... not directly!
201                                             // But he is event listener on THIS instance!
202                                             DispatchProvider* pDispatchHelper = new DispatchProvider( m_xFactory, this );
203                                             css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
204 
205                                             //-------------------------------------------------------------------------------------------------------------
206                                             DispatchInformationProvider* pInfoHelper = new DispatchInformationProvider(m_xFactory, this);
207                                             m_xDispatchInfoHelper = css::uno::Reference< css::frame::XDispatchInformationProvider >( static_cast< ::cppu::OWeakObject* >(pInfoHelper), css::uno::UNO_QUERY );
208 
209                                             //-------------------------------------------------------------------------------------------------------------
210                                             // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
211                                             // Set created dispatch provider as slowest slave of it.
212                                             // Hold interception helper by reference only - not by pointer!
213                                             // So it's easier to destroy it.
214                                             InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
215                                             m_xDispatchHelper = css::uno::Reference< css::frame::XDispatchProvider >( static_cast< ::cppu::OWeakObject* >(pInterceptionHelper), css::uno::UNO_QUERY );
216 
217                                             //-------------------------------------------------------------------------------------------------------------
218                                             // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
219                                             // We hold member as reference ... not as pointer too!
220                                             // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
221                                             // But look on dispose() for right order of deinitialization.
222                                             OFrames* pFramesHelper = new OFrames( m_xFactory, this, &m_aChildFrameContainer );
223                                             m_xFramesHelper = css::uno::Reference< css::frame::XFrames >( static_cast< ::cppu::OWeakObject* >(pFramesHelper), css::uno::UNO_QUERY );
224 
225                                             //-------------------------------------------------------------------------------------------------------------
226                                             // Initialize a the drop target listener.
227                                             // We hold member as reference ... not as pointer too!
228                                             DropTargetListener* pDropListener = new DropTargetListener( m_xFactory, this );
229                                             m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >( static_cast< ::cppu::OWeakObject* >(pDropListener), css::uno::UNO_QUERY );
230 
231                                             // Safe impossible cases
232                                             // We can't work without these helpers!
233                                             LOG_ASSERT2( xDispatchProvider.is    ()==sal_False, "Frame::impl_initService()", "Slowest slave for dispatch- and interception helper isn't valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" )
234                                             LOG_ASSERT2( m_xDispatchHelper.is    ()==sal_False, "Frame::impl_initService()", "Interception helper isn't valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!"                                 )
235                                             LOG_ASSERT2( m_xFramesHelper.is      ()==sal_False, "Frame::impl_initService()", "Frames helper isn't valid. XFrames, XIndexAccess and XElementAccess are not supported!"                                                                )
236                                             LOG_ASSERT2( m_xDropTargetListener.is()==sal_False, "Frame::impl_initService()", "DropTarget helper isn't valid. Drag and drop without functionality!"                                                                                  )
237 
238                                             //-------------------------------------------------------------------------------------------------------------
239                                             // establish notifies for changing of "disabled commands" configuration during runtime
240                                             m_aCommandOptions.EstablisFrameCallback(this);
241 
242                                             //-------------------------------------------------------------------------------------------------------------
243                                             // Create an initial layout manager
244                                             // Create layout manager and connect it to the newly created frame
245                                             m_xLayoutManager = css::uno::Reference< css::frame::XLayoutManager >(m_xFactory->createInstance(SERVICENAME_LAYOUTMANAGER), css::uno::UNO_QUERY);
246 
247                                             //-------------------------------------------------------------------------------------------------------------
248                                             // set information about all supported properties at the base class helper PropertySetHelper
249                                             impl_initializePropInfo();
250                                         }
251                                     )
252 
253 /*-****************************************************************************************************//**
254 	@short		standard constructor to create instance by factory
255 	@descr		This constructor initialize a new instance of this class by valid factory,
256 				and will be set valid values on his member and baseclasses.
257 
258     @attention  a)  Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
259                     will get over this. (e.g. using of your reference as parameter to initialize some member)
260                     Do such things in DEFINE_INIT_SERVICE() method, which is called automatically after your ctor!!!
261                 b)  Baseclass OBroadcastHelper is a typedef in namespace cppu!
262                     The Microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
263                     If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
264                     I don't know why! (other compiler not tested .. but it works!)
265 
266     @seealso    method DEFINE_INIT_SERVICE()
267 
268 	@param		"xFactory" is the multi service manager, which create this instance.
269 				The value must be different from NULL!
270 	@return		-
271 
272 	@onerror	ASSERT in debug version or nothing in release version.
273 *//*-*****************************************************************************************************/
274 Frame::Frame( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
275         :   ThreadHelpBase              ( &Application::GetSolarMutex()                     )
276         ,   TransactionBase             (                                                   )
277         ,   PropertySetHelper           ( xFactory,
278                                           &m_aLock,
279                                           &m_aTransactionManager,
280                                           sal_False) // sal_False => dont release shared mutex on calling us!
281         ,   ::cppu::OWeakObject         (                                                   )
282 		//	init member
283         ,   m_xFactory                  ( xFactory                                          )
284         ,   m_aListenerContainer        ( m_aLock.getShareableOslMutex()                    )
285         ,   m_xParent                   (                                                   )
286         ,   m_xContainerWindow          (                                                   )
287         ,   m_xComponentWindow          (                                                   )
288         ,   m_xController               (                                                   )
289         ,   m_eActiveState              ( E_INACTIVE                                        )
290         ,   m_sName                     (                                                   )
291         ,   m_bIsFrameTop               ( sal_True                                          ) // I think we are top without a parent ... and there is no parent yet!
292         ,   m_bConnected                ( sal_False                                         ) // There exist no component inside of use => sal_False, we are not connected!
293         ,   m_nExternalLockCount        ( 0                                                 )
294         ,   m_bSelfClose                ( sal_False                                         ) // Important!
295         ,   m_bIsHidden                 ( sal_True                                          )
296         ,   m_xTitleHelper              (                                                   )
297 	     ,   mp_WindowCommandDispatch    ( NULL                                              )
298         ,   m_aChildFrameContainer      (                                                   )
299 {
300     // Check incoming parameter to avoid against wrong initialization.
301     LOG_ASSERT2( implcp_ctor( xFactory ), "Frame::Frame()", "Invalid parameter detected!" )
302 
303     /* Please have a look on "@attentions" of description before! */
304 }
305 
306 /*-****************************************************************************************************//**
307 	@short		standard destructor
308 	@descr		This one do NOTHING! Use dispose() instead of this.
309 
310 	@seealso	method dispose()
311 
312 	@param		-
313 	@return		-
314 
315 	@onerror	-
316 *//*-*****************************************************************************************************/
~Frame()317 Frame::~Frame()
318 {
319 	LOG_ASSERT2( m_aTransactionManager.getWorkingMode()!=E_CLOSE, "Frame::~Frame()", "Who forgot to dispose this service?" )
320 	 if (mp_WindowCommandDispatch != NULL)
321 	 {
322 		  delete ((WindowCommandDispatch *)mp_WindowCommandDispatch); // memory leak #i120079#
323 	 }
324 }
325 
326 /*-************************************************************************************************************//**
327     @interface  XComponentLoader
328     @short      try to load given URL into a task
329     @descr      You can give us some informations about the content, which you will load into a frame.
330                 We search or create this target for you, make a type detection of given URL and try to load it.
331                 As result of this operation we return the new created component or nothing, if loading failed.
332 
333     @seealso    -
334 
335     @param      "sURL"              , URL, which represents the content
336     @param      "sTargetFrameName"  , name of target frame or special value like "_self", "_blank" ...
337     @param      "nSearchFlags"      , optional arguments for frame search, if target isn't a special one
338     @param      "lArguments"        , optional arguments for loading
339     @return     A valid component reference, if loading was successfully.
340                 A null reference otherwise.
341 
342     @onerror    We return a null reference.
343     @threadsafe yes
344 *//*-*************************************************************************************************************/
loadComponentFromURL(const::rtl::OUString & sURL,const::rtl::OUString & sTargetFrameName,sal_Int32 nSearchFlags,const css::uno::Sequence<css::beans::PropertyValue> & lArguments)345 css::uno::Reference< css::lang::XComponent > SAL_CALL Frame::loadComponentFromURL( const ::rtl::OUString&                                 sURL            ,
346                                                                                    const ::rtl::OUString&                                 sTargetFrameName,
347                                                                                          sal_Int32                                        nSearchFlags    ,
348                                                                                    const css::uno::Sequence< css::beans::PropertyValue >& lArguments      ) throw( css::io::IOException                ,
349                                                                                                                                                                    css::lang::IllegalArgumentException ,
350                                                                                                                                                                    css::uno::RuntimeException          )
351 {
352     {
353         // If the frame is closed the call might lead to crash even with target "_blank",
354         // so the DisposedException should be thrown in this case
355         // It still looks to be too dangerous to set the transaction for the whole loading process
356         // so the guard is used in scopes to let the standard check be used
357 
358         TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
359     }
360 
361     ReadGuard aReadLock(m_aLock);
362     css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
363     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xFactory;
364     aReadLock.unlock();
365 
366     return LoadEnv::loadComponentFromURL(xThis, xSMGR, sURL, sTargetFrameName, nSearchFlags, lArguments);
367 }
368 
369 /*-****************************************************************************************************//**
370 	@short		return access to append or remove childs on desktop
371 	@descr		We don't implement these interface directly. We use a helper class to do this.
372 				If you wish to add or delete childs to/from the container, call these method to get
373 				a reference to the helper.
374 
375 	@seealso	class OFrames
376 
377 	@param		-
378 	@return		A reference to the helper which answer your queries.
379 
380 	@onerror	A null reference is returned.
381 *//*-*****************************************************************************************************/
getFrames()382 css::uno::Reference< css::frame::XFrames > SAL_CALL Frame::getFrames() throw( css::uno::RuntimeException )
383 {
384 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
385     // Register transaction and reject wrong calls.
386 
387 /*TODO
388     This is a temp. HACK!
389     Our parent (a Task!) stand in close/dispose and set working mode to E_BEFOERECLOSE
390     and call dispose on us! We try to get this xFramesHelper and are reject by an "already closed" parent instance ....
391     => We use SOFTEXCEPTIONS here ... but we should make it right in further times ....
392  */
393 
394     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
395 
396 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
397     ReadGuard aReadLock( m_aLock );
398 
399     // Return access to all child frames to caller.
400     // Our childframe container is implemented in helper class OFrames and used as a reference m_xFramesHelper!
401     return m_xFramesHelper;
402 }
403 
404 /*-****************************************************************************************************//**
405 	@short		get the current active child frame
406 	@descr		It must be a frameto. Direct childs of a frame are frames only! No task or desktop is accepted.
407 				We don't save this information directly in this class. We use our container-helper
408 				to do that.
409 
410 	@seealso	class OFrameContainer
411 	@seealso	method setActiveFrame()
412 
413 	@param		-
414 	@return		A reference to our current active childframe, if anyone exist.
415 	@return		A null reference, if nobody is active.
416 
417 	@onerror	A null reference is returned.
418 *//*-*****************************************************************************************************/
getActiveFrame()419 css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::getActiveFrame() throw( css::uno::RuntimeException )
420 {
421 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
422     // Register transaction and reject wrong calls.
423     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
424 
425     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
426     ReadGuard aReadLock( m_aLock );
427 
428 	// Return current active frame.
429 	// This information is available on the container.
430 	return m_aChildFrameContainer.getActive();
431 }
432 
433 /*-****************************************************************************************************//**
434 	@short		set the new active direct child frame
435 	@descr		It must be a frame to. Direct childs of frame are frames only! No task or desktop is accepted.
436 				We don't save this information directly in this class. We use our container-helper
437 				to do that.
438 
439 	@seealso	class OFrameContainer
440 	@seealso	method getActiveFrame()
441 
442 	@param		"xFrame", reference to new active child. It must be an already existing child!
443 	@return		-
444 
445 	@onerror    An assertion is thrown and element is ignored, if given frame isn't already a child of us.
446 *//*-*****************************************************************************************************/
setActiveFrame(const css::uno::Reference<css::frame::XFrame> & xFrame)447 void SAL_CALL Frame::setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException )
448 {
449 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
450     // Check incoming parameters.
451     LOG_ASSERT2( implcp_setActiveFrame( xFrame ), "Frame::setActiveFrame()", "Invalid parameter detected!" )
452     // Look for rejected calls!
453     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
454 
455 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
456     WriteGuard aWriteLock( m_aLock );
457 
458     // Copy necessary member for threadsafe access!
459     // m_aChildFrameContainer is threadsafe himself and he live if we live!!!
460     // ...and our transaction is non breakable too ...
461     css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
462     EActiveState                              eActiveState = m_eActiveState             ;
463 
464     aWriteLock.unlock();
465     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
466 
467     // Doesn't work, if "new" active frame isn't different from current one!
468     // (xFrame==NULL is allowed to UNSET it!)
469     if( xActiveChild != xFrame )
470     {
471         // ... otherwise set new and deactivate old one.
472         m_aChildFrameContainer.setActive( xFrame );
473         if  (
474                 ( eActiveState      !=  E_INACTIVE  )   &&
475                 ( xActiveChild.is() ==  sal_True    )
476             )
477         {
478             xActiveChild->deactivate();
479         }
480     }
481 
482     if( xFrame.is() == sal_True )
483     {
484         // If last active frame had focus ...
485         // ... reset state to ACTIVE and send right FrameActionEvent for focus lost.
486         if( eActiveState == E_FOCUS )
487         {
488             aWriteLock.lock();
489             eActiveState   = E_ACTIVE    ;
490             m_eActiveState = eActiveState;
491             aWriteLock.unlock();
492             implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
493         }
494 
495         // If last active frame was active ...
496         // but new one isn't it ...
497         // ... set it as active one.
498         if  (
499                 ( eActiveState          ==  E_ACTIVE    )   &&
500                 ( xFrame->isActive()    ==  sal_False   )
501             )
502         {
503             xFrame->activate();
504         }
505     }
506     else
507     // If this frame is active and has no active subframe anymore it is UI active too
508     if( eActiveState == E_ACTIVE )
509     {
510         aWriteLock.lock();
511         eActiveState   = E_FOCUS     ;
512         m_eActiveState = eActiveState;
513         aWriteLock.unlock();
514         implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
515     }
516 }
517 
518 /*-****************************************************************************************************//**
519    initialize new created layout manager
520 **/
lcl_enableLayoutManager(const css::uno::Reference<css::frame::XLayoutManager> & xLayoutManager,const css::uno::Reference<css::frame::XFrame> & xFrame)521 void lcl_enableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager >& xLayoutManager,
522                              const css::uno::Reference< css::frame::XFrame >&         xFrame        )
523 {
524     // Provide container window to our layout manager implementation
525     xLayoutManager->attachFrame(xFrame);
526 
527     css::uno::Reference< css::frame::XFrameActionListener > xListen(xLayoutManager, css::uno::UNO_QUERY_THROW);
528     xFrame->addFrameActionListener(xListen);
529 
530     DockingAreaDefaultAcceptor* pAcceptor = new DockingAreaDefaultAcceptor(xFrame);
531     css::uno::Reference< css::ui::XDockingAreaAcceptor > xDockingAreaAcceptor( static_cast< ::cppu::OWeakObject* >(pAcceptor), css::uno::UNO_QUERY_THROW);
532     xLayoutManager->setDockingAreaAcceptor(xDockingAreaAcceptor);
533 }
534 
535 /*-****************************************************************************************************//**
536    deinitialize layout manager
537 **/
lcl_disableLayoutManager(const css::uno::Reference<css::frame::XLayoutManager> & xLayoutManager,const css::uno::Reference<css::frame::XFrame> & xFrame)538 void lcl_disableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager >& xLayoutManager,
539                               const css::uno::Reference< css::frame::XFrame >&         xFrame        )
540 {
541     css::uno::Reference< css::frame::XFrameActionListener > xListen(xLayoutManager, css::uno::UNO_QUERY_THROW);
542     xFrame->removeFrameActionListener(xListen);
543     xLayoutManager->setDockingAreaAcceptor(css::uno::Reference< css::ui::XDockingAreaAcceptor >());
544     xLayoutManager->attachFrame(css::uno::Reference< css::frame::XFrame >());
545 }
546 
547 /*-****************************************************************************************************//**
548 	@short		initialize frame instance
549 	@descr		A frame needs a window. This method set a new one ... but should called one times only!
550 				We use this window to listen for window events and forward it to our set component.
551 				Its used as parent of component window too.
552 
553 	@seealso	method getContainerWindow()
554 	@seealso	method setComponent()
555 	@seealso	member m_xContainerWindow
556 
557 	@param		"xWindow", reference to new container window - must be valid!
558 	@return		-
559 
560 	@onerror	We do nothing.
561 *//*-*****************************************************************************************************/
initialize(const css::uno::Reference<css::awt::XWindow> & xWindow)562 void SAL_CALL Frame::initialize( const css::uno::Reference< css::awt::XWindow >& xWindow ) throw( css::uno::RuntimeException )
563 {
564 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
565     if (!xWindow.is())
566         throw css::uno::RuntimeException(
567                     ::rtl::OUString::createFromAscii("Frame::initialize() called without a valid container window reference."),
568                     static_cast< css::frame::XFrame* >(this));
569 
570     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
571     WriteGuard aWriteLock( m_aLock );
572 
573     if ( m_xContainerWindow.is() )
574         throw css::uno::RuntimeException(
575                 ::rtl::OUString::createFromAscii("Frame::initialized() is called more then once, which isn't useful nor allowed."),
576                 static_cast< css::frame::XFrame* >(this));
577 
578     // Look for rejected calls first!
579     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
580 
581     // Enable object for real working ... so follow impl methods don't must handle it special! (e.g. E_SOFTEXCEPTIONS for rejected calls)
582     m_aTransactionManager.setWorkingMode( E_WORK );
583 
584     // This must be the first call of this method!
585     // We should initialize our object and open it for working.
586     // Set the new window.
587     LOG_ASSERT2( m_xContainerWindow.is()==sal_True, "Frame::initialize()", "Leak detected! This state should never occur ..." )
588     m_xContainerWindow = xWindow;
589 
590     // if window is initially visible, we will never get a windowShowing event
591     Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
592     if (pWindow && pWindow->IsVisible())
593         m_bIsHidden = sal_False;
594 
595     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR          = m_xFactory;
596     css::uno::Reference< css::frame::XLayoutManager >     xLayoutManager = m_xLayoutManager;
597 
598     // Release lock ... because we call some impl methods, which are threadsafe by himself.
599     // If we hold this lock - we will produce our own deadlock!
600     aWriteLock.unlock();
601 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
602 
603     if (xLayoutManager.is())
604         lcl_enableLayoutManager(xLayoutManager, this);
605 
606     // create progress helper
607     css::uno::Reference< css::frame::XFrame >                 xThis            (static_cast< css::frame::XFrame* >(this)                        , css::uno::UNO_QUERY_THROW);
608     css::uno::Reference< css::task::XStatusIndicatorFactory > xIndicatorFactory(xSMGR->createInstance(IMPLEMENTATIONNAME_STATUSINDICATORFACTORY), css::uno::UNO_QUERY_THROW);
609     css::uno::Reference< css::lang::XInitialization >         xIndicatorInit   (xIndicatorFactory                                               , css::uno::UNO_QUERY_THROW);
610     css::uno::Sequence< css::uno::Any > lArgs(2);
611     css::beans::NamedValue aArg;
612     aArg.Name    = STATUSINDICATORFACTORY_PROPNAME_FRAME;
613     aArg.Value <<= xThis;
614     lArgs[0]   <<= aArg;
615     aArg.Name    = STATUSINDICATORFACTORY_PROPNAME_ALLOWPARENTSHOW;
616     aArg.Value <<= sal_True;
617     lArgs[1]   <<= aArg;
618     xIndicatorInit->initialize(lArgs);
619 
620     // SAFE -> ----------------------------------
621     aWriteLock.lock();
622     m_xIndicatorFactoryHelper = xIndicatorFactory;
623     aWriteLock.unlock();
624     // <- SAFE ----------------------------------
625 
626     // Start listening for events after setting it on helper class ...
627     // So superfluous messages are filtered to NULL :-)
628     implts_startWindowListening();
629 
630     impl_enablePropertySet();
631 
632     // create WindowCommandDispatch; it is supposed to release itself at frame destruction
633     mp_WindowCommandDispatch = new WindowCommandDispatch(xSMGR, this); // memory leak #i120079#
634 
635     // Initialize title functionality
636     TitleHelper* pTitleHelper = new TitleHelper(xSMGR);
637     m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pTitleHelper), css::uno::UNO_QUERY_THROW);
638     pTitleHelper->setOwner(xThis);
639 }
640 
641 /*-****************************************************************************************************//**
642 	@short		returns current set container window
643 	@descr		The ContainerWindow property is used as a container for the component
644 				in this frame. So this object implements a container interface too.
645 				The instantiation of the container window is done by the user of this class.
646 				The frame is the owner of its container window.
647 
648 	@seealso	method initialize()
649 
650 	@param		-
651 	@return		A reference to current set containerwindow.
652 
653 	@onerror	A null reference is returned.
654 *//*-*****************************************************************************************************/
getContainerWindow()655 css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getContainerWindow() throw( css::uno::RuntimeException )
656 {
657 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
658     // Register transaction and reject wrong calls.
659     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
660 
661 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
662     ReadGuard aReadLock( m_aLock );
663 
664     return m_xContainerWindow;
665 }
666 
667 /*-****************************************************************************************************//**
668 	@short		set parent frame
669 	@descr		We need a parent to support some functionality! e.g. findFrame()
670                 By the way we use the chance to set an internal information about our top state.
671                 So we must not check this information during every isTop() call.
672                 We are top, if our parent is the desktop instance or we have no parent.
673 
674     @seealso    getCreator()
675     @seealso    findFrame()
676     @seealso    isTop()
677     @seealos    m_bIsFrameTop
678 
679     @param      xCreator
680                     valid reference to our new owner frame, which should implement a supplier interface
681 
682     @threadsafe yes
683     @modified   08.05.2002 09:35, as96863
684 *//*-*****************************************************************************************************/
setCreator(const css::uno::Reference<css::frame::XFramesSupplier> & xCreator)685 void SAL_CALL Frame::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& xCreator ) throw( css::uno::RuntimeException )
686 {
687     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
688 
689     /* SAFE { */
690         WriteGuard aWriteLock( m_aLock );
691             m_xParent = xCreator;
692         aWriteLock.unlock();
693     /* } SAFE */
694 
695     css::uno::Reference< css::frame::XDesktop > xIsDesktop( xCreator, css::uno::UNO_QUERY );
696     m_bIsFrameTop = ( xIsDesktop.is() || ! xCreator.is() );
697 }
698 
699 /*-****************************************************************************************************//**
700 	@short		returns current parent frame
701 	@descr		The Creator is the parent frame container. If it is NULL, the frame is the uppermost one.
702 
703 	@seealso	method setCreator()
704 
705 	@param		-
706 	@return		A reference to current set parent frame container.
707 
708 	@onerror	A null reference is returned.
709 *//*-*****************************************************************************************************/
getCreator()710 css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Frame::getCreator() throw( css::uno::RuntimeException )
711 {
712 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
713     // Register transaction and reject wrong calls.
714     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
715 
716 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
717     ReadGuard aReadLock( m_aLock );
718 
719     return m_xParent;
720 }
721 
722 /*-****************************************************************************************************//**
723 	@short		returns current set name of frame
724 	@descr		This name is used to find target of findFrame() or queryDispatch() calls.
725 
726 	@seealso	method setName()
727 
728 	@param		-
729 	@return		Current set name of frame.
730 
731 	@onerror	An empty string is returned.
732 *//*-*****************************************************************************************************/
getName()733 ::rtl::OUString SAL_CALL Frame::getName() throw( css::uno::RuntimeException )
734 {
735 	/* SAFE { */
736     ReadGuard aReadLock( m_aLock );
737     return m_sName;
738 	/* } SAFE */
739 }
740 
741 /*-****************************************************************************************************//**
742 	@short		set new name for frame
743 	@descr		This name is used to find target of findFrame() or queryDispatch() calls.
744 
745 	@attention	Special names like "_blank", "_self" aren't allowed ...
746 				"_beamer" or "_menubar" excepts this rule!
747 
748 	@seealso	method getName()
749 
750 	@param		"sName", new frame name.
751 	@return		-
752 
753 	@onerror	We do nothing.
754 *//*-*****************************************************************************************************/
setName(const::rtl::OUString & sName)755 void SAL_CALL Frame::setName( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException )
756 {
757 	/* SAFE { */
758     WriteGuard aWriteLock( m_aLock );
759     // Set new name ... but look for invalid special target names!
760     // They are not allowed to set.
761     if (TargetHelper::isValidNameForFrame(sName))
762         m_sName = sName;
763 	aWriteLock.unlock();
764 	/* } SAFE */
765 }
766 
767 /*-****************************************************************************************************//**
768 	@short		search for frames
769 	@descr		This method searches for a frame with the specified name.
770 				Frames may contain other frames (e.g. a frameset) and may
771 				be contained in other frames. This hierarchy is searched by
772 				this method.
773 				First some special names are taken into account, i.e. "",
774                 "_self", "_top", "_blank" etc. The nSearchFlags are ignored
775 				when comparing these names with sTargetFrameName, further steps are
776 				controlled by the search flags. If allowed, the name of the frame
777 				itself is compared with the desired one, then ( again if allowed )
778                 the method findFrame() is called for all children, for siblings
779                 and as last for the parent frame.
780 				If no frame with the given name is found until the top frames container,
781 				a new top one is created, if this is allowed by a special
782 				flag. The new frame also gets the desired name.
783 
784     @param      sTargetFrameName
785                     special names (_blank, _self) or real name of target frame
786     @param      nSearchFlags
787                     optional flags which regulate search for non special target frames
788 
789     @return     A reference to found or may be new created frame.
790     @threadsafe yes
791     @modified   16.05.2002 11:08, as96863
792 *//*-*****************************************************************************************************/
findFrame(const::rtl::OUString & sTargetFrameName,sal_Int32 nSearchFlags)793 css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::findFrame( const ::rtl::OUString&  sTargetFrameName,
794                                                                            sal_Int32         nSearchFlags    ) throw( css::uno::RuntimeException )
795 {
796     css::uno::Reference< css::frame::XFrame > xTarget;
797 
798     //-----------------------------------------------------------------------------------------------------
799     // 0) Ignore wrong parameter!
800     //    We don't support search for the following special targets.
801     //    If we reject this requests - we must not check for such names
802     //    in following code again and again. If we do not so wrong
803     //    search results can occur!
804     //-----------------------------------------------------------------------------------------------------
805     if (
806         (sTargetFrameName==SPECIALTARGET_DEFAULT  )   ||    // valid for dispatches - not for findFrame()!
807         (sTargetFrameName==SPECIALTARGET_MENUBAR  )   ||    // valid for dispatches - not for findFrame()!
808         (sTargetFrameName==SPECIALTARGET_HELPAGENT)         // valid for dispatches - not for findFrame()!
809        )
810     {
811         return NULL;
812     }
813 
814     //-----------------------------------------------------------------------------------------------------
815     // I) check for special defined targets first which must be handled exclusive.
816     //    force using of "if() else if() ..."
817     //-----------------------------------------------------------------------------------------------------
818 
819     // get threadsafe some necessary member which are necessary for following functionality
820     /* SAFE { */
821     ReadGuard aReadLock( m_aLock );
822     css::uno::Reference< css::frame::XFrame >              xParent      ( m_xParent, css::uno::UNO_QUERY );
823     css::uno::Reference< css::lang::XMultiServiceFactory > xFactory     = m_xFactory;
824     sal_Bool                                               bIsTopFrame  = m_bIsFrameTop;
825     sal_Bool                                               bIsTopWindow = WindowHelper::isTopWindow(m_xContainerWindow);
826     aReadLock.unlock();
827     /* } SAFE */
828 
829     //-----------------------------------------------------------------------------------------------------
830     // I.I) "_blank"
831     //  Not allowed for a normal frame - but for the desktop.
832     //  Use helper class to do so. It use the desktop automatically.
833     //-----------------------------------------------------------------------------------------------------
834     if ( sTargetFrameName==SPECIALTARGET_BLANK )
835     {
836         TaskCreator aCreator(xFactory);
837         xTarget = aCreator.createTask(sTargetFrameName,sal_False);
838     }
839 
840     //-----------------------------------------------------------------------------------------------------
841     // I.II) "_parent"
842     //  It doesn't matter if we have a valid parent or not. User ask for him and get it.
843     //  An empty result is a valid result too.
844     //-----------------------------------------------------------------------------------------------------
845     else
846     if ( sTargetFrameName==SPECIALTARGET_PARENT )
847     {
848         xTarget = xParent;
849     }
850 
851     //-----------------------------------------------------------------------------------------------------
852     // I.III) "_top"
853     //  If we are not the top frame in this hierarchy, we must forward request to our parent.
854     //  Otherwise we must return ourself.
855     //-----------------------------------------------------------------------------------------------------
856     else
857     if ( sTargetFrameName==SPECIALTARGET_TOP )
858     {
859         if (bIsTopFrame)
860             xTarget = this;
861         else
862         if (xParent.is()) // If we are not top - the parent MUST exist. But maybe it's better to check it again .-)
863             xTarget = xParent->findFrame(SPECIALTARGET_TOP,0);
864     }
865 
866     //-----------------------------------------------------------------------------------------------------
867     // I.IV) "_self", ""
868     //  This mean this frame in every case.
869     //-----------------------------------------------------------------------------------------------------
870     else
871     if (
872         ( sTargetFrameName==SPECIALTARGET_SELF ) ||
873         ( sTargetFrameName.getLength()<1       )
874        )
875     {
876         xTarget = this;
877     }
878 
879     //-----------------------------------------------------------------------------------------------------
880     // I.V) "_beamer"
881     //  This is a special sub frame of any task. We must return it if we found it on our direct children
882     //  or create it there if it not already exists.
883     //  Note: Such beamer exists for task(top) frames only!
884     //-----------------------------------------------------------------------------------------------------
885     else
886     if ( sTargetFrameName==SPECIALTARGET_BEAMER )
887     {
888         // We are a task => search or create the beamer
889         if (bIsTopWindow)
890         {
891             xTarget = m_aChildFrameContainer.searchOnDirectChildrens(SPECIALTARGET_BEAMER);
892             if ( ! xTarget.is() )
893             {
894                 /* TODO
895                     Creation not supported yet!
896                     Wait for new layout manager service because we can't plug it
897                     inside already opened document of this frame ...
898                 */
899             }
900         }
901         // We arent a task => forward request to our parent or ignore it.
902         else
903         if (xParent.is())
904             xTarget = xParent->findFrame(SPECIALTARGET_BEAMER,0);
905     }
906 
907     else
908     {
909         //-------------------------------------------------------------------------------------------------
910         // II) otherwise use optional given search flags
911         //  force using of combinations of such flags. means no "else" part of use if() statements.
912         //  But we must break further searches if target was already found.
913         //  Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
914         //  TASK and CREATE are handled special.
915         //-------------------------------------------------------------------------------------------------
916 
917         // get threadsafe some necessary member which are necessary for following functionality
918         /* SAFE { */
919         aReadLock.lock();
920         ::rtl::OUString sOwnName = m_sName;
921         aReadLock.unlock();
922         /* } SAFE */
923 
924         //-------------------------------------------------------------------------------------------------
925         // II.I) SELF
926         //  Check for right name. If it's the searched one return ourself - otherwise
927         //  ignore this flag.
928         //-------------------------------------------------------------------------------------------------
929         if (
930             (nSearchFlags &  css::frame::FrameSearchFlag::SELF) &&
931             (sOwnName     == sTargetFrameName                 )
932            )
933         {
934             xTarget = this;
935         }
936 
937         //-------------------------------------------------------------------------------------------------
938         // II.II) CHILDREN
939         //  Search on all children for the given target name.
940         //  An empty name value can't occur here - because it must be already handled as "_self"
941         //  before. Used helper function of container doesn't create any frame.
942         //  It makes a deep search only.
943         //-------------------------------------------------------------------------------------------------
944         if (
945             ( ! xTarget.is()                                     ) &&
946             (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
947            )
948         {
949             xTarget = m_aChildFrameContainer.searchOnAllChildrens(sTargetFrameName);
950         }
951 
952         //-------------------------------------------------------------------------------------------------
953         // II.III) TASKS
954         //  This is a special flag. It regulate search on this task tree only or allow search on
955         //  all other ones (which are sibling trees of us) too.
956         //  Upper search must stop at this frame if we are the topest one and the TASK flag isn't set
957         //  or we can ignore it if we have no valid parent.
958         //-------------------------------------------------------------------------------------------------
959         if (
960             (   bIsTopFrame && (nSearchFlags & css::frame::FrameSearchFlag::TASKS) ) ||
961             ( ! bIsTopFrame                                                        )
962            )
963         {
964             //-------------------------------------------------------------------------------------------------
965             // II.III.I) SIBLINGS
966             //  Search on all our direct siblings - means all children of our parent.
967             //  Use this flag in combination with TASK. We must suppress such upper search if
968             //  user has not set it and if we are a top frame.
969             //
970             //  Attention: Don't forward this request to our parent as a findFrame() call.
971             //  In such case we must protect us against recursive calls.
972             //  Use snapshot of our parent. But don't use queryFrames() of XFrames interface.
973             //  Because it's return all siblings and all her children including our children too
974             //  if we call it with the CHILDREN flag. We doesn't need that - we need the direct container
975             //  items of our parent only to start searches there. So we must use the container interface
976             //  XIndexAccess instead of XFrames.
977             //-------------------------------------------------------------------------------------------------
978             if (
979                 ( ! xTarget.is()                                      ) &&
980                 (nSearchFlags &  css::frame::FrameSearchFlag::SIBLINGS) &&
981                 (   xParent.is()                                      ) // search on siblings is impossible without a parent
982                )
983             {
984                 css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
985                 if (xSupplier.is())
986                 {
987                     css::uno::Reference< css::container::XIndexAccess > xContainer( xSupplier->getFrames(), css::uno::UNO_QUERY );
988                     if (xContainer.is())
989                     {
990                         sal_Int32 nCount = xContainer->getCount();
991                         for( sal_Int32 i=0; i<nCount; ++i )
992                         {
993                             css::uno::Reference< css::frame::XFrame > xSibling;
994                             if (
995                                 ( !(xContainer->getByIndex(i)>>=xSibling)                                 ) ||  // control unpacking
996                                 ( ! xSibling.is()                                     ) ||  // check for valid items
997                                 ( xSibling==static_cast< ::cppu::OWeakObject* >(this) )     // ignore ourself! (We are a part of this container too - but search on our children was already done.)
998                             )
999                             {
1000                                 continue;
1001                             }
1002 
1003                             // Don't allow upper search here! Use right flags to regulate it.
1004 							// And allow deep search on children only - if it was allowed for us too.
1005 							sal_Int32 nRightFlags = css::frame::FrameSearchFlag::SELF;
1006 							if (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
1007 								nRightFlags |= css::frame::FrameSearchFlag::CHILDREN;
1008                             xTarget = xSibling->findFrame(sTargetFrameName, nRightFlags );
1009                             // perform search be breaking further search if a result exist.
1010                             if (xTarget.is())
1011                                 break;
1012                         }
1013                     }
1014                 }
1015             }
1016 
1017             //-------------------------------------------------------------------------------------------------
1018             // II.III.II) PARENT
1019             //  Forward search to our parent (if he exists.)
1020             //  To prevent us against recursive and superfluous calls (which can occur if we allow him
1021             //  to search on his children too) we must change used search flags.
1022             //-------------------------------------------------------------------------------------------------
1023             if (
1024                 ( ! xTarget.is()                                    ) &&
1025                 (nSearchFlags &  css::frame::FrameSearchFlag::PARENT) &&
1026                 (   xParent.is()                                    )
1027                )
1028             {
1029 				if (xParent->getName() == sTargetFrameName)
1030 					xTarget = xParent;
1031 				else
1032 				{
1033 					sal_Int32 nRightFlags  = nSearchFlags;
1034 							  nRightFlags &= ~css::frame::FrameSearchFlag::CHILDREN;
1035 					xTarget = xParent->findFrame(sTargetFrameName, nRightFlags);
1036 				}
1037             }
1038         }
1039 
1040         //-------------------------------------------------------------------------------------------------
1041         // II.IV) CREATE
1042         //  If we haven't found any valid target frame by using normal flags - but user allowed us to create
1043         //  a new one ... we should do that. Used TaskCreator use Desktop instance automatically as parent!
1044         //-------------------------------------------------------------------------------------------------
1045         if (
1046             ( ! xTarget.is()                                   )    &&
1047             (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
1048            )
1049         {
1050             TaskCreator aCreator(xFactory);
1051             xTarget = aCreator.createTask(sTargetFrameName,sal_False);
1052         }
1053     }
1054 
1055     return xTarget;
1056 }
1057 
1058 /*-****************************************************************************************************//**
1059 	@short		-
1060 	@descr		Returns sal_True, if this frame is a "top frame", otherwise sal_False.
1061 				The "m_bIsFrameTop" member must be set in the ctor or setCreator() method.
1062     			A top frame is a member of the top frame container or a member of the
1063     			task frame container. Both containers can create new frames if the findFrame()
1064                 method of their css::frame::XFrame interface is called with a frame name not yet known.
1065 
1066 	@seealso	ctor
1067 	@seealso	method setCreator()
1068 	@seealso	method findFrame()
1069 
1070 	@param		-
1071 	@return		true, if is it a top frame ... false otherwise.
1072 
1073 	@onerror	No error should occur!
1074 *//*-*****************************************************************************************************/
isTop()1075 sal_Bool SAL_CALL Frame::isTop() throw( css::uno::RuntimeException )
1076 {
1077 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1078     // Register transaction and reject wrong calls.
1079     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1080 
1081 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
1082     ReadGuard aReadLock( m_aLock );
1083 
1084     // This information is set in setCreator().
1085     // We are top, if our parent is a task on the desktop or if no parent exist!
1086     return m_bIsFrameTop;
1087 }
1088 
1089 /*-****************************************************************************************************//**
1090 	@short		activate frame in hierarchy
1091 	@descr		This feature is used to mark active paths in our frame hierarchy.
1092 				You can be a listener for this event to react for it ... change some internal states or something else.
1093 
1094 	@seealso	method deactivate()
1095 	@seealso	method isActivate()
1096 	@seealso	enum EActiveState
1097 	@seealso	listener mechanism
1098 
1099 	@param		-
1100 	@return		-
1101 
1102 	@onerror	-
1103 *//*-*****************************************************************************************************/
activate()1104 void SAL_CALL Frame::activate() throw( css::uno::RuntimeException )
1105 {
1106 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1107     // Register transaction and reject wrong calls.
1108     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1109 
1110 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
1111     WriteGuard aWriteLock( m_aLock );
1112 
1113     // Copy necessary member and free the lock.
1114     // It's not necessary for m_aChildFrameContainer ... because
1115     // he is threadsafe himself and live if we live.
1116     // We use a registered transaction to prevent us against
1117     // breaks during this operation!
1118     css::uno::Reference< css::frame::XFrame >           xActiveChild    = m_aChildFrameContainer.getActive()                                ;
1119     css::uno::Reference< css::frame::XFramesSupplier >  xParent         ( m_xParent, css::uno::UNO_QUERY )                                ;
1120     css::uno::Reference< css::frame::XFrame >           xThis           ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1121     css::uno::Reference< css::awt::XWindow >            xComponentWindow( m_xComponentWindow, css::uno::UNO_QUERY )                       ;
1122     EActiveState                                        eState          = m_eActiveState                                                  ;
1123 
1124     aWriteLock.unlock();
1125     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1126 
1127     //_________________________________________________________________________________________________________
1128     //  1)  If I'am not active before ...
1129     if( eState == E_INACTIVE )
1130     {
1131         // ... do it then.
1132         aWriteLock.lock();
1133         eState         = E_ACTIVE;
1134         m_eActiveState = eState;
1135         aWriteLock.unlock();
1136         // Deactivate sibling path and forward activation to parent ... if any parent exist!
1137         if( xParent.is() == sal_True )
1138         {
1139             // Every time set THIS frame as active child of parent and activate it.
1140             // We MUST have a valid path from bottom to top as active path!
1141             // But we must deactivate the old active sibling path first.
1142 
1143             // Attention: Deactivation of an active path, deactivate the whole path ... from bottom to top!
1144             // But we wish to deactivate founded sibling-tree only.
1145             // [ see deactivate() / step 4) for further informations! ]
1146 
1147             xParent->setActiveFrame( xThis );
1148 
1149             // Then we can activate from here to top.
1150             // Attention: We are ACTIVE now. And the parent will call activate() at us!
1151             // But we do nothing then! We are already activated.
1152             xParent->activate();
1153         }
1154         // It's necessary to send event NOW - not before.
1155         // Activation goes from bottom to top!
1156         // That's the reason to activate parent first and send event now.
1157         implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_ACTIVATED );
1158     }
1159 
1160     //_________________________________________________________________________________________________________
1161     //  2)  I was active before or current activated and there is a path from here to bottom, who CAN be active.
1162     //      But our direct child of path is not active yet.
1163     //      (It can be, if activation occur in the middle of a current path!)
1164     //      In these case we activate path to bottom to set focus on right frame!
1165     if  (
1166             ( eState                    ==  E_ACTIVE    )   &&
1167             ( xActiveChild.is()         ==  sal_True    )   &&
1168             ( xActiveChild->isActive()  ==  sal_False   )
1169         )
1170     {
1171         xActiveChild->activate();
1172     }
1173 
1174     //_________________________________________________________________________________________________________
1175     //  3)  I was active before or current activated. But if I have no active child => I will get the focus!
1176     if  (
1177             ( eState            ==  E_ACTIVE    )   &&
1178             ( xActiveChild.is() ==  sal_False   )
1179         )
1180     {
1181         aWriteLock.lock();
1182         eState         = E_FOCUS;
1183         m_eActiveState = eState;
1184         aWriteLock.unlock();
1185         implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
1186     }
1187 }
1188 
1189 /*-****************************************************************************************************//**
1190 	@short		deactivate frame in hierarchy
1191 	@descr		This feature is used to deactivate paths in our frame hierarchy.
1192 				You can be a listener for this event to react for it ... change some internal states or something else.
1193 
1194 	@seealso	method activate()
1195 	@seealso	method isActivate()
1196 	@seealso	enum EActiveState
1197 	@seealso	listener mechanism
1198 
1199 	@param		-
1200 	@return		-
1201 
1202 	@onerror	-
1203 *//*-*****************************************************************************************************/
deactivate()1204 void SAL_CALL Frame::deactivate() throw( css::uno::RuntimeException )
1205 {
1206 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1207     // Register transaction and reject wrong calls.
1208     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1209 
1210 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
1211     WriteGuard aWriteLock( m_aLock );
1212 
1213     // Copy necessary member and free the lock.
1214     css::uno::Reference< css::frame::XFrame >           xActiveChild    = m_aChildFrameContainer.getActive()                                     ;
1215     css::uno::Reference< css::frame::XFramesSupplier >  xParent         ( m_xParent, css::uno::UNO_QUERY )                                ;
1216     css::uno::Reference< css::frame::XFrame >           xThis           ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1217     EActiveState                                        eState          = m_eActiveState                                                  ;
1218 
1219     aWriteLock.unlock();
1220     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1221 
1222     // Work only, if there something to do!
1223     if( eState != E_INACTIVE )
1224     {
1225         //_____________________________________________________________________________________________________
1226         //  1)  Deactivate all active childs.
1227         if  (
1228                 ( xActiveChild.is()         ==  sal_True    )   &&
1229                 ( xActiveChild->isActive()  ==  sal_True    )
1230             )
1231         {
1232             xActiveChild->deactivate();
1233         }
1234 
1235         //_____________________________________________________________________________________________________
1236         //  2)  If I have the focus - I will lost it now.
1237         if( eState == E_FOCUS )
1238         {
1239             // Set new state INACTIVE(!) and send message to all listener.
1240             // Don't set ACTIVE as new state. This frame is deactivated for next time - due to activate().
1241             aWriteLock.lock();
1242             eState          = E_ACTIVE;
1243             m_eActiveState  = eState  ;
1244             aWriteLock.unlock();
1245             implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
1246         }
1247 
1248         //_____________________________________________________________________________________________________
1249         //  3)  If I'm active - I will be deactivated now.
1250         if( eState == E_ACTIVE )
1251         {
1252             // Set new state and send message to all listener.
1253             aWriteLock.lock();
1254             eState          = E_INACTIVE;
1255             m_eActiveState  = eState    ;
1256             aWriteLock.unlock();
1257             implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_DEACTIVATING );
1258         }
1259 
1260         //_____________________________________________________________________________________________________
1261         //  4)  If there is a path from here to my parent ...
1262         //      ... I'am on the top or in the middle of deactivated subtree and action was started here.
1263         //      I must deactivate all frames from here to top, which are members of current path.
1264         //      Stop, if THESE frame not the active frame of our parent!
1265         if  (
1266                 ( xParent.is()              ==  sal_True    )   &&
1267                 ( xParent->getActiveFrame() ==  xThis       )
1268             )
1269         {
1270             // We MUST break the path - otherwise we will get the focus - not our parent! ...
1271             // Attention: Our parent don't call us again - WE ARE NOT ACTIVE YET!
1272             // [ see step 3 and condition "if ( m_eActiveState!=INACTIVE ) ..." in this method! ]
1273             xParent->deactivate();
1274         }
1275     }
1276 }
1277 
1278 /*-****************************************************************************************************//**
1279 	@short		returns active state
1280 	@descr		Call it to get informations about current active state of this frame.
1281 
1282 	@seealso	method activate()
1283 	@seealso	method deactivate()
1284 	@seealso	enum EActiveState
1285 
1286 	@param		-
1287 	@return		true if active, false otherwise.
1288 
1289 	@onerror	No error should occur.
1290 *//*-*****************************************************************************************************/
isActive()1291 sal_Bool SAL_CALL Frame::isActive() throw( css::uno::RuntimeException )
1292 {
1293 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1294     // Register transaction and reject wrong calls.
1295     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1296 
1297 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
1298     ReadGuard aReadLock( m_aLock );
1299 
1300     return  (
1301                 ( m_eActiveState    ==  E_ACTIVE    )   ||
1302                 ( m_eActiveState    ==  E_FOCUS     )
1303             );
1304 }
1305 
1306 /*-****************************************************************************************************//**
1307 	@short		???
1308 	@descr		-
1309 
1310 	@seealso	-
1311 
1312 	@param		-
1313 	@return		-
1314 
1315 	@onerror	-
1316 *//*-*****************************************************************************************************/
contextChanged()1317 void SAL_CALL Frame::contextChanged() throw( css::uno::RuntimeException )
1318 {
1319     // Look for rejected calls!
1320     // Sometimes called during closing object... => soft exceptions
1321     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1322     // Impl-method is threadsafe himself!
1323 	// Send event to all listener for frame actions.
1324     implts_sendFrameActionEvent( css::frame::FrameAction_CONTEXT_CHANGED );
1325 }
1326 
1327 /*-****************************************************************************************************//**
1328 	@short		set new component inside the frame
1329 	@descr		A frame is a container for a component. Use this method to set, change or release it!
1330 				We accept null references! The xComponentWindow will be a child of our container window
1331 				and get all window events from us.
1332 
1333     @attention  (a) A current set component can disagree with the suspend() request!
1334                     We don't set the new one and return with false then.
1335                 (b) It's possible to set:
1336                         (b1) a simple component here which supports the window only - no controller;
1337                         (b2) a full featured component which supports window and controller;
1338                         (b3) or both to NULL if outside code which to forget this component.
1339 
1340 	@seealso	method getComponentWindow()
1341 	@seealso	method getController()
1342 
1343     @param      xComponentWindow
1344                     valid reference to new component window which will be a child of internal container window
1345                     May <NULL/> for releasing.
1346     @param      xController
1347                     reference to new component controller
1348                     (may <NULL/> for releasing or setting of a simple component)
1349 
1350     @return     <TRUE/> if operation was successful, <FALSE/> otherwise.
1351 
1352     @onerror    We return <FALSE/>.
1353     @threadsafe yes
1354     @modified   06.05.2002 11:39, as96863
1355 *//*-*****************************************************************************************************/
setComponent(const css::uno::Reference<css::awt::XWindow> & xComponentWindow,const css::uno::Reference<css::frame::XController> & xController)1356 sal_Bool SAL_CALL Frame::setComponent(  const   css::uno::Reference< css::awt::XWindow >&       xComponentWindow ,
1357                                         const   css::uno::Reference< css::frame::XController >& xController      ) throw( css::uno::RuntimeException )
1358 {
1359     //_____________________________________________________________________________________________________
1360     // Ignore this HACK of sfx2!
1361     // He calls us with a valid controller without a valid window ... That's not allowed!
1362     if  ( xController.is() && ! xComponentWindow.is() )
1363 		return sal_True;
1364 
1365 	TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1366 
1367     //_____________________________________________________________________________________________________
1368     // Get threadsafe some copies of used members.
1369     /* SAFE { */
1370     ReadGuard aReadLock( m_aLock );
1371     css::uno::Reference< css::awt::XWindow >       xContainerWindow    = m_xContainerWindow;
1372     css::uno::Reference< css::awt::XWindow >       xOldComponentWindow = m_xComponentWindow;
1373     css::uno::Reference< css::frame::XController > xOldController      = m_xController;
1374     Window*                                        pOwnWindow = VCLUnoHelper::GetWindow( xContainerWindow );
1375     sal_Bool                                       bHadFocus           = pOwnWindow->HasChildPathFocus();
1376     sal_Bool                                       bWasConnected       = m_bConnected;
1377     aReadLock.unlock();
1378     /* } SAFE */
1379 
1380     //_____________________________________________________________________________________________________
1381 	// stop listening on old window
1382 	// May it produce some trouble.
1383     // But don't forget to listen on new window again ... or reactivate listening
1384     // if we reject this setComponent() request and leave this method without changing the old window.
1385     implts_stopWindowListening();
1386 
1387 	// Notify all listener, that this component (if current one exist) will be unloaded.
1388 	if (bWasConnected)
1389 		implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_DETACHING );
1390 
1391     //_____________________________________________________________________________________________________
1392     // otherwise release old component first
1393     // Always release controller before releasing window,
1394     // because controller may want to access its window!
1395     // But check for real changes - maybe the new controller is the old one.
1396     if (
1397         (xOldController.is()          )   &&
1398         (xOldController != xController)
1399        )
1400     {
1401         /* ATTENTION
1402             Don't suspend the old controller here. Because the outside caller must do that
1403             by definition. We have to dispose it here only.
1404          */
1405 
1406         // Before we dispose this controller we should hide it inside this frame instance.
1407         // We hold it alive for next calls by using xOldController!
1408         /* SAFE {*/
1409         WriteGuard aWriteLock( m_aLock );
1410         m_xController = NULL;
1411         aWriteLock.unlock();
1412         /* } SAFE */
1413 
1414         css::uno::Reference< css::lang::XComponent > xDisposable( xOldController, css::uno::UNO_QUERY );
1415         if (xDisposable.is())
1416         {
1417             try
1418             {
1419                 xDisposable->dispose();
1420             }
1421             catch(const css::lang::DisposedException&)
1422                 {}
1423         }
1424 	    xOldController = NULL;
1425     }
1426 
1427     //_____________________________________________________________________________________________________
1428     // Now it's time to release the component window.
1429     // If controller wasn't released successfully - this code line shouldn't be reached.
1430     // Because in case of "suspend()==false" we return immediately with false ...
1431     // see before
1432     // Check for real changes too.
1433     if (
1434         (xOldComponentWindow.is()               )   &&
1435         (xOldComponentWindow != xComponentWindow)
1436        )
1437     {
1438         /* SAFE { */
1439         WriteGuard aWriteLock( m_aLock );
1440         m_xComponentWindow = NULL;
1441         aWriteLock.unlock();
1442         /* } SAFE */
1443 
1444         css::uno::Reference< css::lang::XComponent > xDisposable( xOldComponentWindow, css::uno::UNO_QUERY );
1445         if (xDisposable.is())
1446         {
1447             try
1448             {
1449                 xDisposable->dispose();
1450             }
1451             catch(const css::lang::DisposedException&)
1452                 {}
1453         }
1454 	    xOldComponentWindow = NULL;
1455     }
1456 
1457     //_____________________________________________________________________________________________________
1458     // Now it's time to set the new component ...
1459     // By the way - find out our new "load state" - means if we have a valid component inside.
1460     /* SAFE { */
1461     WriteGuard aWriteLock( m_aLock );
1462 	m_xComponentWindow = xComponentWindow;
1463     m_xController      = xController     ;
1464     m_bConnected       = (m_xComponentWindow.is() || m_xController.is());
1465     sal_Bool bIsConnected       = m_bConnected;
1466     aWriteLock.unlock();
1467     /* } SAFE */
1468 
1469     //_____________________________________________________________________________________________________
1470 	// notifies all interest listener, that current component was changed or a new one was loaded
1471     if (bIsConnected && bWasConnected)
1472         implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_REATTACHED );
1473     else
1474     if (bIsConnected && !bWasConnected)
1475         implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_ATTACHED   );
1476 
1477     //_____________________________________________________________________________________________________
1478     // A new component window doesn't know anything about current active/focus states.
1479     // Set this information on it!
1480     if (
1481         (bHadFocus            ) &&
1482         (xComponentWindow.is())
1483        )
1484     {
1485         xComponentWindow->setFocus();
1486     }
1487 
1488     // If it was a new component window - we must resize it to fill out
1489     // our container window.
1490     implts_resizeComponentWindow();
1491     // New component should change our current icon ...
1492     implts_setIconOnWindow();
1493 	// OK - start listening on new window again - or do nothing if it is an empty one.
1494     implts_startWindowListening();
1495 
1496     /* SAFE { */
1497     aWriteLock.lock();
1498     impl_checkMenuCloser();
1499     aWriteLock.unlock();
1500     /* } SAFE */
1501 
1502 	return sal_True;
1503 }
1504 
1505 /*-****************************************************************************************************//**
1506 	@short		returns current set component window
1507 	@descr		Frames are used to display components. The actual displayed component is
1508 				held by the m_xComponentWindow property. If the component implements only a
1509 				XComponent interface, the communication between the frame and the
1510 				component is very restricted. Better integration is achievable through a
1511 				XController interface.
1512 				If the component wants other objects to be able to get information about its
1513 				ResourceDescriptor it has to implement a XModel interface.
1514 				This frame is the owner of the component window.
1515 
1516 	@seealso	method setComponent()
1517 
1518 	@param		-
1519     @return     css::uno::Reference to current set component window.
1520 
1521 	@onerror	A null reference is returned.
1522 *//*-*****************************************************************************************************/
getComponentWindow()1523 css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getComponentWindow() throw( css::uno::RuntimeException )
1524 {
1525 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1526     // Register transaction and reject wrong calls.
1527     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1528 
1529 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
1530     ReadGuard aReadLock( m_aLock );
1531 
1532     return m_xComponentWindow;
1533 }
1534 
1535 /*-****************************************************************************************************//**
1536 	@short		returns current set controller
1537 	@descr		Frames are used to display components. The actual displayed component is
1538 				held by the m_xComponentWindow property. If the component implements only a
1539 				XComponent interface, the communication between the frame and the
1540 				component is very restricted. Better integration is achievable through a
1541 				XController interface.
1542 				If the component wants other objects to be able to get information about its
1543 				ResourceDescriptor it has to implement a XModel interface.
1544 				This frame is the owner of the component window.
1545 
1546 	@seealso	method setComponent()
1547 
1548 	@param		-
1549     @return     css::uno::Reference to current set controller.
1550 
1551 	@onerror	A null reference is returned.
1552 *//*-*****************************************************************************************************/
getController()1553 css::uno::Reference< css::frame::XController > SAL_CALL Frame::getController() throw( css::uno::RuntimeException )
1554 {
1555 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1556     // It seems to be unavoidable that disposed frames allow to ask for a Controller (#111452)
1557     // Register transaction and reject wrong calls.
1558     // TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1559 
1560 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
1561     ReadGuard aReadLock( m_aLock );
1562 
1563     return m_xController;
1564 }
1565 
1566 /*-****************************************************************************************************//**
1567 	@short		add/remove listener for activate/deactivate/contextChanged events
1568 	@descr		-
1569 
1570 	@seealso	method activate()
1571 	@seealso	method deactivate()
1572 	@seealso	method contextChanged()
1573 
1574 	@param		"xListener" reference to your listener object
1575 	@return		-
1576 
1577 	@onerror	Listener is ignored.
1578 *//*-*****************************************************************************************************/
addFrameActionListener(const css::uno::Reference<css::frame::XFrameActionListener> & xListener)1579 void SAL_CALL Frame::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException )
1580 {
1581 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1582 	// Check incoming parameter.
1583     LOG_ASSERT2( implcp_addFrameActionListener( xListener ), "Frame::addFrameActionListener()", "Invalid parameter detected." )
1584     // Listener container is threadsafe by himself ... but we must look for rejected calls!
1585     // Our OMenuDispatch-helper (is a member of ODispatchProvider!) is create at startup of this frame BEFORE initialize!
1586     // => soft exceptions!
1587     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1588 
1589 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
1590     m_aListenerContainer.addInterface( ::getCppuType( (const css::uno::Reference< css::frame::XFrameActionListener >*)NULL ), xListener );
1591 }
1592 
1593 //*****************************************************************************************************************
removeFrameActionListener(const css::uno::Reference<css::frame::XFrameActionListener> & xListener)1594 void SAL_CALL Frame::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException )
1595 {
1596 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1597 	// Check incoming parameter.
1598     LOG_ASSERT2( implcp_removeFrameActionListener( xListener ), "Frame::removeFrameActionListener()", "Invalid parameter detected." )
1599 	// Listener container is threadsafe by himself ... but we must look for rejected calls after disposing!
1600     // But we must work with E_SOFTEXCEPTIONS ... because sometimes we are called from our listeners
1601     // during dispose! Our work mode is E_BEFORECLOSE then ... and E_HARDEXCEPTIONS whould throw a DisposedException.
1602     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1603 
1604 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
1605     m_aListenerContainer.removeInterface( ::getCppuType( (const css::uno::Reference< css::frame::XFrameActionListener >*)NULL ), xListener );
1606 }
1607 
1608 /*-****************************************************************************************************//**
1609     @short      support two way mechanism to release a frame
1610     @descr      This method ask internal component (controller) if he accepts this close request.
1611                 In case of <TRUE/> nothing will be happen (from point of caller of this close method).
1612                 In case of <FALSE/> a CloseVetoException is thrown. After such exception given parameter
1613                 <var>bDeliverOwnerShip</var> regulate which will be the new owner of this instance.
1614 
1615     @attention  It's the replacement for XTask::close() which is marked as obsolete method.
1616 
1617     @param      bDeliverOwnerShip
1618                     If parameter is set to <FALSE/> the original caller will be the owner after thrown
1619                     veto exception and must try to close this frame at later time again. Otherwise the
1620                     source of throwed exception is the right one. Maybe it will be the frame himself.
1621 
1622     @thrown     CloseVetoException
1623                     if any internal things can not be closed
1624 
1625     @threadsafe yes
1626     @modified   06.05.2002 08:33, as96863
1627 *//*-*****************************************************************************************************/
close(sal_Bool bDeliverOwnerShip)1628 void SAL_CALL Frame::close( sal_Bool bDeliverOwnerShip ) throw( css::util::CloseVetoException,
1629                                                                 css::uno::RuntimeException   )
1630 {
1631     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1632 
1633     // At the end of this method may we must dispose ourself ...
1634     // and may nobody from outside hold a reference to us ...
1635     // then it's a good idea to do that by ourself.
1636     css::uno::Reference< css::uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
1637 
1638     // Check any close listener before we look for currently running internal processes.
1639     // Because if a listener disagree with this close() request - we have time to finish this
1640     // internal operations too ...
1641     // Note: container is threadsafe himself.
1642     css::lang::EventObject             aSource    (static_cast< ::cppu::OWeakObject*>(this));
1643     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >*) NULL ) );
1644     if (pContainer!=NULL)
1645 	{
1646         ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
1647         while (pIterator.hasMoreElements())
1648         {
1649             try
1650             {
1651                 ((css::util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnerShip );
1652             }
1653             catch( css::uno::RuntimeException& )
1654             {
1655                 pIterator.remove();
1656             }
1657         }
1658 	}
1659 
1660     // Ok - no listener disagreed with this close() request
1661     // check if this frame is used for any load process currently
1662     if (isActionLocked())
1663     {
1664         if (bDeliverOwnerShip)
1665 		{
1666 			/* SAFE */
1667 			WriteGuard aWriteLock( m_aLock );
1668 			m_bSelfClose = sal_True;
1669 			aWriteLock.unlock();
1670 			/* SAFE */
1671 		}
1672 
1673 		throw css::util::CloseVetoException(DECLARE_ASCII("Frame in use for loading document ..."),static_cast< ::cppu::OWeakObject*>(this));
1674     }
1675 
1676     if ( ! setComponent(NULL,NULL) )
1677         throw css::util::CloseVetoException(DECLARE_ASCII("Component couldn't be deattached ..."),static_cast< ::cppu::OWeakObject*>(this));
1678 
1679     // If closing is allowed ... inform all listener and dispose this frame!
1680     pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >*) NULL ) );
1681     if (pContainer!=NULL)
1682 	{
1683         ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
1684         while (pIterator.hasMoreElements())
1685         {
1686             try
1687             {
1688                 ((css::util::XCloseListener*)pIterator.next())->notifyClosing( aSource );
1689             }
1690             catch( css::uno::RuntimeException& )
1691             {
1692                 pIterator.remove();
1693             }
1694         }
1695 	}
1696 
1697     /* SAFE { */
1698 	WriteGuard aWriteLock( m_aLock );
1699     m_bIsHidden = sal_True;
1700     aWriteLock.unlock();
1701     /* } SAFE */
1702     impl_checkMenuCloser();
1703 
1704     // Attention: We must release our own registered transaction here. Otherwise following dispose() call
1705     // waits for us too ....
1706     aTransaction.stop();
1707     dispose();
1708 }
1709 
1710 /*-****************************************************************************************************//**
1711     @short      be a listener for close events!
1712     @descr      Adds/remove a CloseListener at this frame instance. If the close() method is called on
1713                 this object, the such listener are informed and can disagree with that by throwing
1714                 a CloseVetoException.
1715 
1716     @seealso    Frame::close()
1717 
1718     @param      xListener
1719                     reference to your listener object
1720 
1721 	@onerror	Listener is ignored.
1722 
1723     @threadsafe yes
1724     @modified   06.05.2002 10:03, as96863
1725 *//*-*****************************************************************************************************/
addCloseListener(const css::uno::Reference<css::util::XCloseListener> & xListener)1726 void SAL_CALL Frame::addCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException)
1727 {
1728     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1729     // We don't need any lock here ...
1730     // Container lives if we live and is threadsafe by himself.
1731     m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >* ) NULL ), xListener );
1732 }
1733 
1734 //*****************************************************************************************************************
removeCloseListener(const css::uno::Reference<css::util::XCloseListener> & xListener)1735 void SAL_CALL Frame::removeCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException)
1736 {
1737     // Use soft exception mode - mostly this method is called during disposing of this frame ...
1738     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1739     // We don't need any lock here ...
1740     // Container lives if we live and is threadsafe by himself.
1741     m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::util::XCloseListener >* ) NULL ), xListener );
1742 }
1743 
1744 //*****************************************************************************************************************
getTitle()1745 ::rtl::OUString SAL_CALL Frame::getTitle()
1746     throw (css::uno::RuntimeException)
1747 {
1748     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1749 
1750 	// SAFE ->
1751 	ReadGuard aReadLock(m_aLock);
1752 	css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1753 	aReadLock.unlock();
1754 	// <- SAFE
1755 
1756     return xTitle->getTitle();
1757 }
1758 
1759 //*****************************************************************************************************************
setTitle(const::rtl::OUString & sTitle)1760 void SAL_CALL Frame::setTitle( const ::rtl::OUString& sTitle )
1761     throw (css::uno::RuntimeException)
1762 {
1763     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1764 
1765 	// SAFE ->
1766 	ReadGuard aReadLock(m_aLock);
1767 	css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1768 	aReadLock.unlock();
1769 	// <- SAFE
1770 
1771     xTitle->setTitle(sTitle);
1772 }
1773 
1774 //*****************************************************************************************************************
addTitleChangeListener(const css::uno::Reference<css::frame::XTitleChangeListener> & xListener)1775 void SAL_CALL Frame::addTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
1776     throw (css::uno::RuntimeException)
1777 {
1778     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1779 
1780 	// SAFE ->
1781 	ReadGuard aReadLock(m_aLock);
1782 	css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1783 	aReadLock.unlock();
1784 	// <- SAFE
1785 
1786     xTitle->addTitleChangeListener(xListener);
1787 }
1788 
1789 //*****************************************************************************************************************
removeTitleChangeListener(const css::uno::Reference<css::frame::XTitleChangeListener> & xListener)1790 void SAL_CALL Frame::removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
1791     throw (css::uno::RuntimeException)
1792 {
1793     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1794 
1795 	// SAFE ->
1796 	ReadGuard aReadLock(m_aLock);
1797 	css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1798 	aReadLock.unlock();
1799 	// <- SAFE
1800 
1801     xTitle->removeTitleChangeListener(xListener);
1802 }
1803 
1804 /*-****************************************************************************************************/
implts_forgetSubFrames()1805 void Frame::implts_forgetSubFrames()
1806 {
1807 	// SAFE ->
1808 	ReadGuard aReadLock(m_aLock);
1809 	css::uno::Reference< css::container::XIndexAccess > xContainer(m_xFramesHelper, css::uno::UNO_QUERY_THROW);
1810 	aReadLock.unlock();
1811 	// <- SAFE
1812 
1813 	sal_Int32 c = xContainer->getCount();
1814 	sal_Int32 i = 0;
1815 
1816 	for (i=0; i<c; ++i)
1817 	{
1818 		try
1819 		{
1820 			css::uno::Reference< css::frame::XFrame > xFrame;
1821 			xContainer->getByIndex(i) >>= xFrame;
1822 			if (xFrame.is())
1823 				xFrame->setCreator(css::uno::Reference< css::frame::XFramesSupplier >());
1824 		}
1825 		catch(const css::uno::Exception&)
1826 		{
1827 			// Ignore errors here.
1828 			// Nobody can guarantee a stable index in multi threaded environments .-)
1829 		}
1830 	}
1831 
1832 	// SAFE ->
1833 	WriteGuard aWriteLock(m_aLock);
1834     m_xFramesHelper.clear(); // clear uno reference
1835     m_aChildFrameContainer.clear(); // clear container content
1836 	aWriteLock.unlock();
1837 	// <- SAFE
1838 }
1839 
1840 /*-****************************************************************************************************//**
1841 	@short		destroy instance
1842 	@descr		The owner of this object calls the dispose method if the object
1843 				should be destroyed. All other objects and components, that are registered
1844 				as an EventListener are forced to release their references to this object.
1845 				Furthermore this frame is removed from its parent frame container to release
1846 				this reference. The reference attributes are disposed and released also.
1847 
1848 	@attention	Look for globale description at beginning of file too!
1849 				(DisposedException, FairRWLock ..., initialize, dispose)
1850 
1851 	@seealso	method initialize()
1852 	@seealso	baseclass FairRWLockBase!
1853 
1854 	@param		-
1855 	@return		-
1856 
1857 	@onerror	-
1858 *//*-*****************************************************************************************************/
dispose()1859 void SAL_CALL Frame::dispose() throw( css::uno::RuntimeException )
1860 {
1861     // We should hold a reference to ourself ...
1862     // because our owner dispose us and release our reference ...
1863     // May be we will die before we could finish this method ...
1864     css::uno::Reference< css::frame::XFrame > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1865 
1866     LOG_DISPOSEEVENT( "Frame", sName )
1867 
1868     // First operation should be ... "stop all listening for window events on our container window".
1869     // These events are superfluous but can make trouble!
1870     // We will die, die and die ...
1871     implts_stopWindowListening();
1872 
1873     // Send message to all listener and forget her references.
1874     css::lang::EventObject aEvent( xThis );
1875     m_aListenerContainer.disposeAndClear( aEvent );
1876 
1877     // set "end of live" for our property set helper
1878     impl_disablePropertySet();
1879 
1880     // interception/dispatch chain must be destructed explicitly
1881     // Otherwise some dispatches and/or interception objects won't die.
1882     css::uno::Reference< css::lang::XEventListener > xDispatchHelper(m_xDispatchHelper, css::uno::UNO_QUERY_THROW);
1883     xDispatchHelper->disposing(aEvent);
1884     xDispatchHelper.clear();
1885 
1886     // Disable this instance for further work.
1887     // This will wait for all current running ones ...
1888     // and reject all further requests!
1889     m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
1890 
1891     // Don't show any dialogs, errors or something else any more!
1892     // If somewhere called dispose() without close() before - normally no dialogs
1893     // should exist. Otherwise it's the problem of the outside caller.
1894     // Note:
1895     //      (a) Do it after stopWindowListening(). May that force some active/deactive
1896     //          notifications which we doesn't need here really.
1897     //      (b) Don't forget to save the old value of IsDialogCancelEnabled() to
1898     //          restore it afterwards. We cannot call EnableDialogCancel( sal_False )
1899     //          as we would kill the headless mode!
1900     sal_Bool bCancelDialogs( Application::IsDialogCancelEnabled() );
1901     Application::EnableDialogCancel( sal_True );
1902 
1903     // We should be alone for ever and further dispose calls are rejected by lines before ...
1904     // I hope it :-)
1905 
1906     // Free references of our frame tree.
1907     // Force parent container to forget this frame too ...
1908     // ( It's contained in m_xParent and so no css::lang::XEventListener for m_xParent! )
1909     // It's important to do that before we free some other internal structures.
1910     // Because if our parent gets an activate and found us as last possible active frame
1911     // he try to deactivate us ... and we run into some trouble (DisposedExceptions!).
1912     if( m_xParent.is() == sal_True )
1913     {
1914         m_xParent->getFrames()->remove( xThis );
1915         m_xParent = css::uno::Reference< css::frame::XFramesSupplier >();
1916     }
1917 
1918     /* } SAFE */
1919     // Forget our internal component and her window first.
1920     // So we can release our container window later without problems.
1921     // Because this container window is the parent of the component window ...
1922     // Note: Dispose it hard - because suspending must be done inside close() call!
1923 	// But try to dispose the controller first before you destroy the window.
1924 	// Because the window is used by the controller too ...
1925     if (m_xController.is())
1926     {
1927         css::uno::Reference< css::lang::XComponent > xDisposable( m_xController, css::uno::UNO_QUERY );
1928         if (xDisposable.is())
1929             xDisposable->dispose();
1930     }
1931 
1932     if (m_xComponentWindow.is())
1933     {
1934         css::uno::Reference< css::lang::XComponent > xDisposable( m_xComponentWindow, css::uno::UNO_QUERY );
1935         if (xDisposable.is())
1936             xDisposable->dispose();
1937     }
1938 
1939     impl_checkMenuCloser();
1940 
1941     impl_disposeContainerWindow( m_xContainerWindow );
1942 
1943     /*ATTENTION
1944         Clear container after successful removing from parent container ...
1945         because our parent could be the desktop which stand in dispose too!
1946         If we have already cleared our own container we lost our child before this could be
1947         remove himself at this instance ...
1948         Release m_xFramesHelper after that ... it's the same problem between parent and child!
1949         "m_xParent->getFrames()->remove( xThis );" needs this helper ...
1950         Otherwise we get a null reference and could finish removing successfully.
1951         => You see: Order of calling operations is important!!!
1952      */
1953 	implts_forgetSubFrames();
1954 
1955     // Release some other references.
1956     // This calls should be easy ... I hope it :-)
1957     m_xDispatchHelper.clear();
1958     m_xFactory.clear();
1959     m_xDropTargetListener.clear();
1960     m_xDispatchRecorderSupplier.clear();
1961     m_xLayoutManager.clear();
1962     m_xIndicatorFactoryHelper.clear();
1963 
1964     // It's important to set default values here!
1965     // If may be later somewhere change the disposed-behavior of this implementation
1966     // and doesn't throw any DisposedExceptions we must guarantee best matching default values ...
1967     m_eActiveState       = E_INACTIVE;
1968     m_sName              = ::rtl::OUString();
1969     m_bIsFrameTop        = sal_False;
1970     m_bConnected         = sal_False;
1971     m_nExternalLockCount = 0;
1972     m_bSelfClose         = sal_False;
1973     m_bIsHidden          = sal_True;
1974 
1975     // Disable this instance for further working really!
1976     m_aTransactionManager.setWorkingMode( E_CLOSE );
1977 
1978     // Don't forget it restore old value -
1979     // otherwise no dialogs can be shown anymore in other frames.
1980     Application::EnableDialogCancel( bCancelDialogs );
1981 }
1982 
1983 /*-****************************************************************************************************//**
1984 	@short		Be a listener for dispose events!
1985 	@descr		Adds/remove an EventListener to this object. If the dispose method is called on
1986 				this object, the disposing method of the listener is called.
1987 
1988 	@seealso	-
1989 
1990 	@param		"xListener" reference to your listener object.
1991 	@return		-
1992 
1993 	@onerror	Listener is ignored.
1994 *//*-*****************************************************************************************************/
addEventListener(const css::uno::Reference<css::lang::XEventListener> & xListener)1995 void SAL_CALL Frame::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
1996 {
1997 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1998 	// Check incoming parameter.
1999     LOG_ASSERT2( implcp_addEventListener( xListener ), "Frame::addEventListener()", "Invalid parameter detected." )
2000     // Look for rejected calls only!
2001     // Container is threadsafe.
2002     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2003 
2004 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2005     m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
2006 }
2007 
2008 //*****************************************************************************************************************
removeEventListener(const css::uno::Reference<css::lang::XEventListener> & xListener)2009 void SAL_CALL Frame::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
2010 {
2011 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2012 	// Check incoming parameter.
2013     LOG_ASSERT2( implcp_removeEventListener( xListener ), "Frame::removeEventListener()", "Invalid parameter detected." )
2014     // Look for rejected calls only!
2015     // Container is threadsafe.
2016     // Use E_SOFTEXCEPTIONS to allow removing listeners during dispose call!
2017     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2018 
2019 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2020     m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
2021 }
2022 
2023 /*-****************************************************************************************************//**
2024 	@short		create new status indicator
2025 	@descr		Use returned status indicator to show progresses and some text informations.
2026 				All created objects share the same dialog! Only the last one can show his information.
2027 
2028     @seealso    class StatusIndicatorFactory
2029     @seealso    class StatusIndicator
2030 
2031 	@param		-
2032 	@return		A reference to created object.
2033 
2034 	@onerror	We return a null reference.
2035 *//*-*****************************************************************************************************/
createStatusIndicator()2036 css::uno::Reference< css::task::XStatusIndicator > SAL_CALL Frame::createStatusIndicator() throw( css::uno::RuntimeException )
2037 {
2038     /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
2039     // Look for rejected calls!
2040     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2041 
2042 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2043     ReadGuard aReadLock( m_aLock );
2044 
2045     // Make snapshot of necessary member and define default return value.
2046     css::uno::Reference< css::task::XStatusIndicator >        xExternal(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
2047     css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory = m_xIndicatorFactoryHelper;
2048 
2049     aReadLock.unlock();
2050     /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
2051 
2052     // Was set from outside to intercept any progress activities!
2053     if (xExternal.is())
2054         return xExternal;
2055 
2056     // Or use our own factory as fallback, to create such progress.
2057     if (xFactory.is())
2058         return xFactory->createStatusIndicator();
2059 
2060 	return css::uno::Reference< css::task::XStatusIndicator >();
2061 }
2062 
2063 /*-****************************************************************************************************//**
2064 	@short		search for target to load URL
2065 	@descr		This method searches for a dispatch for the specified DispatchDescriptor.
2066 				The FrameSearchFlags and the FrameName of the DispatchDescriptor are
2067 				treated as described for findFrame.
2068 
2069 	@seealso	method findFrame()
2070 	@seealso	method queryDispatches()
2071 	@seealso	method set/getName()
2072 	@seealso	class TargetFinder
2073 
2074 	@param		"aURL"				, URL for loading
2075 	@param		"sTargetFrameName"	, name of target frame
2076 	@param		"nSearchFlags"		, additional flags to regulate search if sTargetFrameName isn't clear
2077     @return     css::uno::Reference to dispatch handler.
2078 
2079 	@onerror	A null reference is returned.
2080 *//*-*****************************************************************************************************/
queryDispatch(const css::util::URL & aURL,const::rtl::OUString & sTargetFrameName,sal_Int32 nSearchFlags)2081 css::uno::Reference< css::frame::XDispatch > SAL_CALL Frame::queryDispatch( const css::util::URL&   aURL            ,
2082                                                                             const ::rtl::OUString&  sTargetFrameName,
2083                                                                                   sal_Int32         nSearchFlags    ) throw( css::uno::RuntimeException )
2084 {
2085 	const char UNO_PROTOCOL[] = ".uno:";
2086 
2087 	// Don't check incoming parameter here! Our helper do it for us and it isn't a good idea to do it more then ones!
2088     // But look for rejected calls!
2089     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2090 
2091 	// Remove uno and cmd protocol part as we want to support both of them. We store only the command part
2092 	// in our hash map. All other protocols are stored with the protocol part.
2093 	String aCommand( aURL.Main );
2094 	if ( aURL.Protocol.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL, sizeof( UNO_PROTOCOL )-1 ))
2095 		aCommand = aURL.Path;
2096 
2097 	// Make hash_map lookup if the current URL is in the disabled list
2098 	if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
2099 		return css::uno::Reference< css::frame::XDispatch >();
2100 	else
2101 	{
2102 		// We use a helper to support these interface and an interceptor mechanism.
2103 		// Our helper is threadsafe by himself!
2104 		return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
2105 	}
2106 }
2107 
2108 /*-****************************************************************************************************//**
2109 	@short		handle more then ones dispatches at same call
2110     @descr      Returns a sequence of dispatches. For details see the queryDispatch method.
2111 				For failed dispatches we return empty items in list!
2112 
2113 	@seealso	method queryDispatch()
2114 
2115 	@param		"lDescriptor" list of dispatch arguments for queryDispatch()!
2116 	@return		List of dispatch references. Some elements can be NULL!
2117 
2118 	@onerror	An empty list is returned.
2119 *//*-*****************************************************************************************************/
queryDispatches(const css::uno::Sequence<css::frame::DispatchDescriptor> & lDescriptor)2120 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL Frame::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException )
2121 {
2122 	// Don't check incoming parameter here! Our helper do it for us and it isn't a good idea to do it more then ones!
2123     // But look for rejected calls!
2124     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2125 
2126 	// We use a helper to support these interface and an interceptor mechanism.
2127     // Our helper is threadsafe by himself!
2128     return m_xDispatchHelper->queryDispatches( lDescriptor );
2129 }
2130 
2131 /*-****************************************************************************************************//**
2132 	@short		register/unregister interceptor for dispatch calls
2133 	@descr		If you whish to handle some dispatches by himself ... you should be
2134 				an interceptor for it. Please see class OInterceptionHelper for further informations.
2135 
2136 	@seealso	class OInterceptionHelper
2137 
2138 	@param		"xInterceptor", reference to your interceptor implementation.
2139 	@return		-
2140 
2141 	@onerror	Interceptor is ignored.
2142 *//*-*****************************************************************************************************/
registerDispatchProviderInterceptor(const css::uno::Reference<css::frame::XDispatchProviderInterceptor> & xInterceptor)2143 void SAL_CALL Frame::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException )
2144 {
2145 	// We use a helper to support these interface and an interceptor mechanism.
2146     // This helper is threadsafe himself and check incoming parameter too.
2147     // I think we don't need any lock here!
2148     // But we must look for rejected calls.
2149     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2150 
2151     css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
2152     xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
2153 }
2154 
2155 //*****************************************************************************************************************
releaseDispatchProviderInterceptor(const css::uno::Reference<css::frame::XDispatchProviderInterceptor> & xInterceptor)2156 void SAL_CALL Frame::releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException )
2157 {
2158 	// We use a helper to support these interface and an interceptor mechanism.
2159     // This helper is threadsafe himself and check incoming parameter too.
2160     // I think we don't need any lock here!
2161     // But we must look for rejected calls ...
2162     // Sometimes we are called during our dispose() method ... => soft exceptions!
2163     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2164 
2165     css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
2166     xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
2167 }
2168 
2169 /*-****************************************************************************************************//**
2170 	@short		provides information about all possible dispatch functions
2171                 inside the current frame environment
2172 *//*-*****************************************************************************************************/
getSupportedCommandGroups()2173 css::uno::Sequence< sal_Int16 > SAL_CALL Frame::getSupportedCommandGroups()
2174     throw(css::uno::RuntimeException)
2175 {
2176     return m_xDispatchInfoHelper->getSupportedCommandGroups();
2177 }
2178 
2179 //*****************************************************************************************************************
getConfigurableDispatchInformation(sal_Int16 nCommandGroup)2180 css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL Frame::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
2181     throw(css::uno::RuntimeException)
2182 {
2183     return m_xDispatchInfoHelper->getConfigurableDispatchInformation(nCommandGroup);
2184 }
2185 
2186 /*-****************************************************************************************************//**
2187 	@short		notifications for window events
2188 	@descr		We are a listener on our container window to forward it to our component window.
2189 
2190 	@seealso	method setComponent()
2191 	@seealso	member m_xContainerWindow
2192 	@seealso	member m_xComponentWindow
2193 
2194 	@param		"aEvent" describe source of detected event
2195 	@return		-
2196 
2197 	@onerror	-
2198 *//*-*****************************************************************************************************/
windowResized(const css::awt::WindowEvent & aEvent)2199 void SAL_CALL Frame::windowResized( const css::awt::WindowEvent&
2200 #if OSL_DEBUG_LEVEL > 0
2201 aEvent
2202 #endif
2203 ) throw( css::uno::RuntimeException )
2204 {
2205 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2206 	// Check incoming parameter.
2207     LOG_ASSERT2( implcp_windowResized( aEvent ), "Frame::windowResized()", "Invalid parameter detected." )
2208     // Look for rejected calls.
2209     // Part of dispose-mechanism => soft exceptions
2210     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2211 
2212 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2213 	// Impl-method is threadsafe!
2214 	// If we have a current component window - we must resize it!
2215     implts_resizeComponentWindow();
2216 }
2217 
2218 //*****************************************************************************************************************
focusGained(const css::awt::FocusEvent & aEvent)2219 void SAL_CALL Frame::focusGained( const css::awt::FocusEvent&
2220 #if OSL_DEBUG_LEVEL > 0
2221 aEvent
2222 #endif
2223 ) throw( css::uno::RuntimeException )
2224 {
2225 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2226 	// Check incoming parameter.
2227     LOG_ASSERT2( implcp_focusGained( aEvent ), "Frame::focusGained()", "Invalid parameter detected." )
2228     // Look for rejected calls.
2229     // Part of dispose() mechanism ... => soft exceptions!
2230     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2231 
2232 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2233     ReadGuard aReadLock( m_aLock );
2234     // Make snapshot of member!
2235     css::uno::Reference< css::awt::XWindow > xComponentWindow = m_xComponentWindow;
2236     aReadLock.unlock();
2237     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2238 
2239     if( xComponentWindow.is() == sal_True )
2240     {
2241         xComponentWindow->setFocus();
2242     }
2243 }
2244 
2245 /*-****************************************************************************************************//**
2246 	@short		notifications for window events
2247 	@descr		We are a listener on our container window to forward it to our component window ...
2248 				but a XTopWindowListener we are only if we are a top frame!
2249 
2250 	@seealso	method setComponent()
2251 	@seealso	member m_xContainerWindow
2252 	@seealso	member m_xComponentWindow
2253 
2254 	@param		"aEvent" describe source of detected event
2255 	@return		-
2256 
2257 	@onerror	-
2258 *//*-*****************************************************************************************************/
windowActivated(const css::lang::EventObject & aEvent)2259 void SAL_CALL Frame::windowActivated( const css::lang::EventObject&
2260 #if OSL_DEBUG_LEVEL > 0
2261 aEvent
2262 #endif
2263 ) throw( css::uno::RuntimeException )
2264 {
2265 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2266 	// Check incoming parameter.
2267     LOG_ASSERT2( implcp_windowActivated( aEvent ), "Frame::windowActivated()", "Invalid parameter detected." )
2268     // Look for rejected calls.
2269     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2270 
2271 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2272     ReadGuard aReadLock( m_aLock );
2273     // Make snapshot of member!
2274     EActiveState eState = m_eActiveState;
2275     aReadLock.unlock();
2276     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2277     // Activate the new active path from here to top.
2278     if( eState == E_INACTIVE )
2279     {
2280 //       CheckMenuCloser_Impl();
2281         setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
2282         activate();
2283     }
2284 }
2285 
2286 //*****************************************************************************************************************
windowDeactivated(const css::lang::EventObject & aEvent)2287 void SAL_CALL Frame::windowDeactivated( const css::lang::EventObject&
2288 #if OSL_DEBUG_LEVEL > 0
2289 aEvent
2290 #endif
2291 ) throw( css::uno::RuntimeException )
2292 {
2293 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2294 	// Check incoming parameter.
2295     LOG_ASSERT2( implcp_windowDeactivated( aEvent ), "Frame::windowDeactivated()", "Invalid parameter detected." )
2296     // Look for rejected calls.
2297     // Sometimes called during dispose() => soft exceptions
2298     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2299 
2300 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2301     ReadGuard aReadLock( m_aLock );
2302 
2303     css::uno::Reference< css::frame::XFrame > xParent          ( m_xParent, css::uno::UNO_QUERY );
2304     css::uno::Reference< css::awt::XWindow >  xContainerWindow = m_xContainerWindow;
2305     EActiveState                              eActiveState     = m_eActiveState    ;
2306 
2307     aReadLock.unlock();
2308 
2309     if( eActiveState != E_INACTIVE )
2310     {
2311         // Deactivation is always done implicitly by activation of another frame.
2312         // Only if no activation is done, deactivations have to be processed if the activated window
2313         // is a parent window of the last active Window!
2314         ::vos::OClearableGuard aSolarGuard( Application::GetSolarMutex() );
2315 //       CheckMenuCloser_Impl();
2316         Window* pFocusWindow = Application::GetFocusWindow();
2317         if  (
2318                 ( xContainerWindow.is()                                                              ==  sal_True    )   &&
2319                 ( xParent.is()                                                                       ==  sal_True    )   &&
2320                 ( (css::uno::Reference< css::frame::XDesktop >( xParent, css::uno::UNO_QUERY )).is() ==  sal_False   )
2321             )
2322         {
2323             css::uno::Reference< css::awt::XWindow >  xParentWindow   = xParent->getContainerWindow()             ;
2324             Window*                                   pParentWindow   = VCLUnoHelper::GetWindow( xParentWindow    );
2325             //#i70261#: dialogs opened from an OLE object will cause a deactivate on the frame of the OLE object
2326             // on Solaris/Linux at that time pFocusWindow is still NULL because the focus handling is different; right after
2327             // the deactivation the focus will be set into the dialog!
2328             // currently I see no case where a sub frame could get a deactivate with pFocusWindow being NULL permanently
2329             // so for now this case is omitted from handled deactivations
2330             if( pFocusWindow && pParentWindow->IsChild( pFocusWindow ) )
2331             {
2332                 css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
2333                 if( xSupplier.is() == sal_True )
2334                 {
2335                     aSolarGuard.clear();
2336                     xSupplier->setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
2337                 }
2338             }
2339         }
2340     }
2341 }
2342 
2343 //*****************************************************************************************************************
windowClosing(const css::lang::EventObject &)2344 void SAL_CALL Frame::windowClosing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
2345 {
2346     /* #i62088#
2347         Some interceptor objects intercept our "internally asynchronous implemented" dispatch call.
2348         And they close this frame directly (means synchronous then).
2349         Means: Frame::windowClosing()->Frame::close()
2350         In such situation it's not a good idea to hold this transaction count alive .-)
2351     */
2352     {
2353         // Look for rejected calls.
2354         TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2355         // deactivate this frame ...
2356     	deactivate();
2357     }
2358 
2359     // ... and try to close it
2360     // But do it asynchron inside the main thread.
2361     // VCL has no fun to do such things outside his main thread :-(
2362     // Note: The used dispatch make it asynchronous for us .-)
2363 
2364     /*ATTENTION!
2365         Don't try to suspend the controller here! Because it's done inside used dispatch().
2366         Otherwise the dialog "would you save your changes?" will be shown more than once ...
2367      */
2368 
2369     /* SAFE */
2370     ReadGuard aReadLock( m_aLock );
2371     css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
2372     aReadLock.unlock();
2373     /* SAFE */
2374 
2375     css::util::URL aURL;
2376     aURL.Complete = DECLARE_ASCII(".uno:CloseFrame");
2377     css::uno::Reference< css::util::XURLTransformer > xParser(xFactory->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
2378     xParser->parseStrict(aURL);
2379 
2380     css::uno::Reference< css::frame::XDispatch > xCloser = queryDispatch(aURL, SPECIALTARGET_SELF, 0);
2381     if (xCloser.is())
2382         xCloser->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >());
2383 
2384     // Attention: If this dispatch works synchronous ... and full fill its job ...
2385     // this line of code will never be reached ...
2386     // Or if it will be reached it will be for sure that all your member are gone .-)
2387 }
2388 
2389 /*-****************************************************************************************************//**
2390     @short      react for a show event for the internal container window
2391     @descr      Normally we don't need this information really. But we can use it to
2392                 implement the special feature "trigger first visible task".
2393 
2394                 Algorithm: - first we have to check if we are a top (task) frame
2395                              It's not enough to be a top frame! Because we MUST have the desktop as parent.
2396                              But frames without a parent are top too. So it's not possible to check isTop() here!
2397                              We have to look for the type of our parent.
2398                            - if we are a task frame, then we have to check if we are the first one.
2399                              We use a static variable to do so. They will be reset to afterwards be sure
2400                              that further calls of this method doesn't do anything then.
2401                            - Then we have to trigger the right event string on the global job executor.
2402 
2403     @seealso    css::task::JobExecutor
2404 
2405     @param      aEvent
2406                     describes the source of this event
2407                     We are not interested on this information. We are interested on the visible state only.
2408 
2409     @threadsafe yes
2410     @modified   31.07.2002 07:56, as96863
2411 *//*-*****************************************************************************************************/
windowShown(const css::lang::EventObject &)2412 void SAL_CALL Frame::windowShown( const css::lang::EventObject& ) throw(css::uno::RuntimeException)
2413 {
2414     static sal_Bool bFirstVisibleTask = sal_True;
2415 
2416     /* SAFE { */
2417     ReadGuard aReadLock(m_aLock);
2418     css::uno::Reference< css::frame::XDesktop >             xDesktopCheck( m_xParent, css::uno::UNO_QUERY );
2419     css::uno::Reference< css::lang::XMultiServiceFactory >  xFactory     = m_xFactory;
2420     m_bIsHidden = sal_False;
2421     aReadLock.unlock();
2422     /* } SAFE */
2423 
2424     impl_checkMenuCloser();
2425 
2426     if (xDesktopCheck.is())
2427     {
2428         /* STATIC SAFE { */
2429         WriteGuard aStaticWriteLock( LockHelper::getGlobalLock() );
2430         sal_Bool bMustBeTriggered  = bFirstVisibleTask;
2431                  bFirstVisibleTask = sal_False;
2432         aStaticWriteLock.unlock();
2433         /* } STATIC SAFE */
2434 
2435         if (bMustBeTriggered)
2436         {
2437             css::uno::Reference< css::task::XJobExecutor > xExecutor( xFactory->createInstance( SERVICENAME_JOBEXECUTOR ), css::uno::UNO_QUERY );
2438             if (xExecutor.is())
2439             {
2440                 xExecutor->trigger( DECLARE_ASCII("onFirstVisibleTask") );
2441             }
2442         }
2443     }
2444 }
2445 
windowHidden(const css::lang::EventObject &)2446 void SAL_CALL Frame::windowHidden( const css::lang::EventObject& ) throw(css::uno::RuntimeException)
2447 {
2448     /* SAFE { */
2449     ReadGuard aReadLock(m_aLock);
2450     m_bIsHidden = sal_True;
2451     aReadLock.unlock();
2452     /* } SAFE */
2453 
2454     impl_checkMenuCloser();
2455 }
2456 
2457 /*-****************************************************************************************************//**
2458 	@short		called by dispose of our windows!
2459 	@descr		This object is forced to release all references to the interfaces given
2460 				by the parameter source. We are a listener at our container window and
2461 				should listen for his disposing.
2462 
2463 	@seealso	XWindowListener
2464 	@seealso	XTopWindowListener
2465 	@seealso	XFocusListener
2466 
2467 	@param		-
2468 	@return		-
2469 
2470 	@onerror	-
2471 *//*-*****************************************************************************************************/
disposing(const css::lang::EventObject & aEvent)2472 void SAL_CALL Frame::disposing( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException )
2473 {
2474 	/* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2475 	// Check incoming parameter.
2476     LOG_ASSERT2( implcp_disposing( aEvent ), "Frame::disposing()", "Invalid parameter detected." )
2477     // Look for rejected calls.
2478     // May be we are called during releasing our windows in our in dispose call!? => soft exceptions
2479     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2480 
2481 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2482     WriteGuard aWriteLock( m_aLock );
2483 
2484     if( aEvent.Source == m_xContainerWindow )
2485     {
2486         // NECESSARY: Impl-method is threadsafe by himself!
2487         aWriteLock.unlock();
2488         implts_stopWindowListening();
2489         aWriteLock.lock();
2490         m_xContainerWindow = css::uno::Reference< css::awt::XWindow >();
2491     }
2492 }
2493 
2494 /*-************************************************************************************************************//**
2495     @interface  com.sun.star.document.XActionLockable
2496     @short      implement locking of frame/task from outside
2497     @descr      Sometimes we have problems to decide if closing of task is allowed. Because; frame/task
2498                 could be used for pending loading jobs. So you can lock this object from outside and
2499                 prevent instance against closing during using! But - don't do it in a wrong or expensive manner.
2500                 Otherwise task couldn't die anymore!!!
2501 
2502     @seealso    interface XActionLockable
2503     @seeelso    method BaseDispatcher::implts_loadIt()
2504     @seeelso    method Desktop::loadComponentFromURL()
2505 
2506     @param      -
2507     @return     true if frame/task is locked
2508                 false otherwise
2509 
2510     @onerror    -
2511     @threadsafe yes
2512 *//*-*************************************************************************************************************/
isActionLocked()2513 sal_Bool SAL_CALL Frame::isActionLocked() throw( css::uno::RuntimeException )
2514 {
2515 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2516     ReadGuard aReadLock( m_aLock );
2517     return( m_nExternalLockCount!=0);
2518 }
2519 
2520 //*****************************************************************************************************************
addActionLock()2521 void SAL_CALL Frame::addActionLock() throw( css::uno::RuntimeException )
2522 {
2523 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2524     WriteGuard aWriteLock( m_aLock );
2525     ++m_nExternalLockCount;
2526 }
2527 
2528 //*****************************************************************************************************************
removeActionLock()2529 void SAL_CALL Frame::removeActionLock() throw( css::uno::RuntimeException )
2530 {
2531 	// Register no transaction here! Otherwise we wait for ever inside possible
2532 	// implts_checkSuicide()/dispose() request ...
2533 
2534     /* SAFE AREA */{
2535         WriteGuard aWriteLock( m_aLock );
2536         LOG_ASSERT2( m_nExternalLockCount<=0, "Frame::removeActionLock()", "Frame isn't locked! Possible multithreading problem detected." )
2537         --m_nExternalLockCount;
2538     }/* SAFE */
2539 
2540     implts_checkSuicide();
2541 }
2542 
2543 //*****************************************************************************************************************
setActionLocks(sal_Int16 nLock)2544 void SAL_CALL Frame::setActionLocks( sal_Int16 nLock ) throw( css::uno::RuntimeException )
2545 {
2546 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2547     WriteGuard aWriteLock( m_aLock );
2548     // Attention: If somewhere called resetActionLocks() before and get e.g. 5 locks ...
2549     //            and tried to set these 5 ones here after his operations ...
2550     //            we can't ignore set requests during these two calls!
2551     //            So we must add(!) these 5 locks here.
2552     m_nExternalLockCount = m_nExternalLockCount + nLock;
2553 }
2554 
2555 //*****************************************************************************************************************
resetActionLocks()2556 sal_Int16 SAL_CALL Frame::resetActionLocks() throw( css::uno::RuntimeException )
2557 {
2558 	// Register no transaction here! Otherwise we wait for ever inside possible
2559 	// implts_checkSuicide()/dispose() request ...
2560 
2561     sal_Int16 nCurrentLocks = 0;
2562     /* SAFE */{
2563         WriteGuard aWriteLock( m_aLock );
2564         nCurrentLocks = m_nExternalLockCount;
2565         m_nExternalLockCount = 0;
2566     }/* SAFE */
2567 
2568     // Attention:
2569 	// external lock count is 0 here every time ... but if
2570     // member m_bSelfClose is set to true too .... we call our own close()/dispose().
2571     // See close() for further informations
2572     implts_checkSuicide();
2573 
2574     return nCurrentLocks;
2575 }
2576 
2577 //*****************************************************************************************************************
impl_initializePropInfo()2578 void Frame::impl_initializePropInfo()
2579 {
2580     impl_setPropertyChangeBroadcaster(static_cast< css::frame::XFrame* >(this));
2581 
2582     impl_addPropertyInfo(
2583         css::beans::Property(
2584             FRAME_PROPNAME_DISPATCHRECORDERSUPPLIER,
2585             FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER,
2586             ::getCppuType((const css::uno::Reference< css::frame::XDispatchRecorderSupplier >*)NULL),
2587             css::beans::PropertyAttribute::TRANSIENT));
2588 
2589     impl_addPropertyInfo(
2590         css::beans::Property(
2591             FRAME_PROPNAME_INDICATORINTERCEPTION,
2592             FRAME_PROPHANDLE_INDICATORINTERCEPTION,
2593             ::getCppuType((const css::uno::Reference< css::task::XStatusIndicator >*)NULL),
2594             css::beans::PropertyAttribute::TRANSIENT));
2595 
2596     impl_addPropertyInfo(
2597         css::beans::Property(
2598             FRAME_PROPNAME_ISHIDDEN,
2599             FRAME_PROPHANDLE_ISHIDDEN,
2600             ::getBooleanCppuType(),
2601             css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY));
2602 
2603     impl_addPropertyInfo(
2604         css::beans::Property(
2605             FRAME_PROPNAME_LAYOUTMANAGER,
2606             FRAME_PROPHANDLE_LAYOUTMANAGER,
2607             ::getCppuType((const css::uno::Reference< ::com::sun::star::frame::XLayoutManager >*)NULL),
2608             css::beans::PropertyAttribute::TRANSIENT));
2609 
2610     impl_addPropertyInfo(
2611         css::beans::Property(
2612             FRAME_PROPNAME_TITLE,
2613             FRAME_PROPHANDLE_TITLE,
2614             ::getCppuType((const ::rtl::OUString*)NULL),
2615             css::beans::PropertyAttribute::TRANSIENT));
2616 }
2617 
2618 //*****************************************************************************************************************
impl_setPropertyValue(const::rtl::OUString &,sal_Int32 nHandle,const css::uno::Any & aValue)2619 void SAL_CALL Frame::impl_setPropertyValue(const ::rtl::OUString& /*sProperty*/,
2620                                                  sal_Int32        nHandle  ,
2621                                            const css::uno::Any&   aValue   )
2622 
2623 {
2624     static ::rtl::OUString MATERIALPROP_TITLE = ::rtl::OUString::createFromAscii("title");
2625 
2626     /* There is no need to lock any mutex here. Because we share the
2627        solar mutex with our base class. And we said to our base class: "don't release it on calling us" .-)
2628        see ctor of PropertySetHelper for further informations.
2629     */
2630 
2631     /* Attention: You can use nHandle only, if you are sure that all supported
2632                   properties has an unique handle. That must be guaranteed
2633                   inside method impl_initializePropInfo()!
2634     */
2635 	switch (nHandle)
2636 	{
2637         case FRAME_PROPHANDLE_TITLE :
2638                 {
2639                     ::rtl::OUString sExternalTitle;
2640                     aValue >>= sExternalTitle;
2641 					setTitle (sExternalTitle);
2642                 }
2643                 break;
2644 
2645         case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
2646                 aValue >>= m_xDispatchRecorderSupplier;
2647                 break;
2648 
2649         case FRAME_PROPHANDLE_LAYOUTMANAGER :
2650                 {
2651                     css::uno::Reference< css::frame::XLayoutManager > xOldLayoutManager = m_xLayoutManager;
2652                     css::uno::Reference< css::frame::XLayoutManager > xNewLayoutManager;
2653                     aValue >>= xNewLayoutManager;
2654 
2655                     if (xOldLayoutManager != xNewLayoutManager)
2656                     {
2657                         m_xLayoutManager = xNewLayoutManager;
2658                         if (xOldLayoutManager.is())
2659                             lcl_disableLayoutManager(xOldLayoutManager, this);
2660                         if (xNewLayoutManager.is())
2661                             lcl_enableLayoutManager(xNewLayoutManager, this);
2662                     }
2663                 }
2664                 break;
2665 
2666         case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
2667                 {
2668                     css::uno::Reference< css::task::XStatusIndicator > xProgress;
2669                     aValue >>= xProgress;
2670                     m_xIndicatorInterception = xProgress;
2671                 }
2672                 break;
2673 
2674         #ifdef ENABLE_WARNINGS
2675         default :
2676                 LOG_WARNING( "Frame::setFastPropertyValue_NoBroadcast()", "Invalid handle detected!" )
2677                 break;
2678 		#endif
2679 	}
2680 }
2681 
2682 //*****************************************************************************************************************
impl_getPropertyValue(const::rtl::OUString &,sal_Int32 nHandle)2683 css::uno::Any SAL_CALL Frame::impl_getPropertyValue(const ::rtl::OUString& /*sProperty*/,
2684                                                           sal_Int32        nHandle  )
2685 {
2686     /* There is no need to lock any mutex here. Because we share the
2687        solar mutex with our base class. And we said to our base class: "don't release it on calling us" .-)
2688        see ctor of PropertySetHelper for further informations.
2689     */
2690 
2691     /* Attention: You can use nHandle only, if you are sure that all supported
2692                   properties has an unique handle. That must be guaranteed
2693                   inside method impl_initializePropInfo()!
2694     */
2695     css::uno::Any aValue;
2696 	switch (nHandle)
2697 	{
2698         case FRAME_PROPHANDLE_TITLE :
2699 				aValue <<= getTitle ();
2700                 break;
2701 
2702         case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
2703                 aValue <<= m_xDispatchRecorderSupplier;
2704                 break;
2705 
2706         case FRAME_PROPHANDLE_ISHIDDEN :
2707                 aValue <<= m_bIsHidden;
2708                 break;
2709 
2710         case FRAME_PROPHANDLE_LAYOUTMANAGER :
2711                 aValue <<= m_xLayoutManager;
2712                 break;
2713 
2714         case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
2715                 {
2716                     css::uno::Reference< css::task::XStatusIndicator > xProgress(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
2717                     aValue = css::uno::makeAny(xProgress);
2718                 }
2719                 break;
2720 
2721         #ifdef ENABLE_WARNINGS
2722         default :
2723                 LOG_WARNING( "Frame::getFastPropertyValue()", "Invalid handle detected!" )
2724                 break;
2725 		#endif
2726 	}
2727 
2728     return aValue;
2729 }
2730 
2731 /*-****************************************************************************************************//**
2732     @short      dispose old container window and forget his reference
2733     @descr      Sometimes we must repair our "modal dialog parent mechanism" too!
2734 
2735 	@seealso	-
2736 
2737     @param      "xWindow", reference to old container window to dispose it
2738     @return     An empty reference.
2739 
2740     @onerror    -
2741     @threadsafe NO!
2742 *//*-*****************************************************************************************************/
impl_disposeContainerWindow(css::uno::Reference<css::awt::XWindow> & xWindow)2743 void Frame::impl_disposeContainerWindow( css::uno::Reference< css::awt::XWindow >& xWindow )
2744 {
2745     if( xWindow.is() == sal_True )
2746     {
2747         xWindow->setVisible( sal_False );
2748         // All VclComponents are XComponents; so call dispose before discarding
2749         // a css::uno::Reference< XVclComponent >, because this frame is the owner of the window
2750         xWindow->dispose();
2751         xWindow = css::uno::Reference< css::awt::XWindow >();
2752     }
2753 }
2754 
2755 /*-****************************************************************************************************//**
2756 	@short		send frame action event to our listener
2757 	@descr		This method is threadsafe AND can be called by our dispose method too!
2758 
2759 	@seealso	-
2760 
2761 	@param		"aAction", describe the event for sending
2762 	@return		-
2763 
2764 	@onerror	-
2765 *//*-*****************************************************************************************************/
implts_sendFrameActionEvent(const css::frame::FrameAction & aAction)2766 void Frame::implts_sendFrameActionEvent( const css::frame::FrameAction& aAction )
2767 {
2768     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2769     // Sometimes used by dispose() => soft exceptions!
2770     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2771 
2772 	// Log informations about order of events to file!
2773 	// (only activated in debug version!)
2774 	LOG_FRAMEACTIONEVENT( "Frame", m_sName, aAction )
2775 
2776 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2777     // Send css::frame::FrameAction event to all listener.
2778 	// Get container for right listener.
2779     // FOLLOW LINES ARE THREADSAFE!!!
2780     // ( OInterfaceContainerHelper is synchronized with m_aListenerContainer! )
2781     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XFrameActionListener >*) NULL ) );
2782 
2783 	if( pContainer != NULL )
2784 	{
2785 		// Build action event.
2786         css::frame::FrameActionEvent aFrameActionEvent( static_cast< ::cppu::OWeakObject* >(this), this, aAction );
2787 
2788 		// Get iterator for access to listener.
2789         ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
2790 		// Send message to all listener.
2791         while( aIterator.hasMoreElements() == sal_True )
2792 		{
2793             try
2794             {
2795                 ((css::frame::XFrameActionListener*)aIterator.next())->frameAction( aFrameActionEvent );
2796             }
2797             catch( css::uno::RuntimeException& )
2798             {
2799                 aIterator.remove();
2800             }
2801 		}
2802 	}
2803 }
2804 
2805 /*-****************************************************************************************************//**
2806 	@short		helper to resize our component window
2807 	@descr		A frame contains 2 windows - a container ~ and a component window.
2808 				This method resize inner component window to full size of outer container window.
2809 				This method is threadsafe AND can be called by our dispose method too!
2810 
2811 	@seealso	-
2812 
2813 	@param		-
2814 	@return		-
2815 
2816 	@onerror	-
2817 *//*-*****************************************************************************************************/
implts_resizeComponentWindow()2818 void Frame::implts_resizeComponentWindow()
2819 {
2820 	// usually the LayoutManager does the resizing
2821     // in case there is no LayoutManager resizing has to be done here
2822     if ( !m_xLayoutManager.is() )
2823     {
2824         css::uno::Reference< css::awt::XWindow > xComponentWindow( getComponentWindow() );
2825         if( xComponentWindow.is() == sal_True )
2826         {
2827             css::uno::Reference< css::awt::XDevice > xDevice( getContainerWindow(), css::uno::UNO_QUERY );
2828 
2829             // Convert relativ size to output size.
2830             css::awt::Rectangle  aRectangle  = getContainerWindow()->getPosSize();
2831             css::awt::DeviceInfo aInfo       = xDevice->getInfo();
2832             css::awt::Size       aSize       (  aRectangle.Width  - aInfo.LeftInset - aInfo.RightInset  ,
2833                                                 aRectangle.Height - aInfo.TopInset  - aInfo.BottomInset );
2834 
2835             // Resize our component window.
2836             xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );
2837         }
2838     }
2839 }
2840 
2841 /*-****************************************************************************************************//**
2842     @short      helper to set icon on our container window (if it is a system window!)
2843     @descr      We use our internal set controller (if it exists) to specify which factory he represented.
2844                 These information can be used to find right icon. But our controller can say it us directly
2845                 too ... we should ask his optional property set first ...
2846 
2847     @seealso    method Window::SetIcon()
2848 
2849     @param      -
2850     @return     -
2851 
2852     @onerror    We do nothing.
2853 *//*-*****************************************************************************************************/
implts_setIconOnWindow()2854 void Frame::implts_setIconOnWindow()
2855 {
2856     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2857     // Look for rejected calls.
2858     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2859 
2860 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
2861     // Make snapshot of necessary members and release lock.
2862     ReadGuard aReadLock( m_aLock );
2863     css::uno::Reference< css::awt::XWindow >       xContainerWindow( m_xContainerWindow, css::uno::UNO_QUERY );
2864     css::uno::Reference< css::frame::XController > xController     ( m_xController     , css::uno::UNO_QUERY );
2865     aReadLock.unlock();
2866     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2867 
2868     if(
2869         ( xContainerWindow.is() == sal_True )   &&
2870         ( xController.is()      == sal_True )
2871       )
2872     {
2873         //-------------------------------------------------------------------------------------------------------------
2874         // a) set default value to an invalid one. So we can start further searches for right icon id, if
2875         //    first steps failed!
2876         //    We must reset it to any fallback value - if no search step returns a valid result.
2877         sal_Int32 nIcon = -1;
2878 
2879         //-------------------------------------------------------------------------------------------------------------
2880         // b) try to find information on controller propertyset directly
2881         //    Don't forget to catch possible exceptions - because these property is an optional one!
2882         css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY );
2883         if( xSet.is() == sal_True )
2884         {
2885             try
2886             {
2887                 css::uno::Reference< css::beans::XPropertySetInfo > const xPSI( xSet->getPropertySetInfo(), css::uno::UNO_SET_THROW );
2888                 if ( xPSI->hasPropertyByName( CONTROLLER_PROPNAME_ICONID ) )
2889                     xSet->getPropertyValue( CONTROLLER_PROPNAME_ICONID ) >>= nIcon;
2890             }
2891             catch( css::uno::Exception& )
2892             {
2893                 DBG_UNHANDLED_EXCEPTION();
2894             }
2895         }
2896 
2897         //-------------------------------------------------------------------------------------------------------------
2898         // c) if b) failed ... analyze argument list of currently loaded document inside the frame to find the filter.
2899         //    He can be used to detect right factory - and these can be used to match factory to icon ...
2900         if( nIcon == -1 )
2901         {
2902             css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
2903             if( xModel.is() == sal_True )
2904             {
2905                 SvtModuleOptions::EFactory eFactory = SvtModuleOptions::ClassifyFactoryByModel(xModel);
2906                 if (eFactory != SvtModuleOptions::E_UNKNOWN_FACTORY)
2907                     nIcon = SvtModuleOptions().GetFactoryIcon( eFactory );
2908             }
2909         }
2910 
2911         //-------------------------------------------------------------------------------------------------------------
2912         // d) if all steps failed - use fallback!
2913         if( nIcon == -1 )
2914         {
2915             nIcon = 0;
2916         }
2917 
2918         //-------------------------------------------------------------------------------------------------------------
2919         // e) set icon on container window now
2920         //    Don't forget SolarMutex! We use vcl directly :-(
2921         //    Check window pointer for right WorkWindow class too!!!
2922         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2923         ::vos::OClearableGuard aSolarGuard( Application::GetSolarMutex() );
2924         Window* pWindow = (VCLUnoHelper::GetWindow( xContainerWindow ));
2925         if(
2926             ( pWindow            != NULL              ) &&
2927             ( pWindow->GetType() == WINDOW_WORKWINDOW )
2928         )
2929         {
2930             WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
2931             pWorkWindow->SetIcon( (sal_uInt16)nIcon );
2932         }
2933         aSolarGuard.clear();
2934         /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2935     }
2936 }
2937 
2938 /*-************************************************************************************************************//**
2939     @short      helper to start/stop listening for window events on container window
2940     @descr      If we get a new container window, we must set it on internal member ...
2941                 and stop listening at old one ... and start listening on new one!
2942                 But sometimes (in dispose() call!) it's necessary to stop listening without starting
2943                 on new connections. So we split this functionality to make it easier at use.
2944 
2945     @seealso    method initialize()
2946     @seealso    method dispose()
2947 
2948     @param      -
2949     @return     -
2950 
2951     @onerror    We do nothing!
2952     @threadsafe yes
2953 *//*-*************************************************************************************************************/
implts_startWindowListening()2954 void Frame::implts_startWindowListening()
2955 {
2956     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2957     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2958 
2959     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2960     // Make snapshot of necessary member!
2961     ReadGuard aReadLock( m_aLock );
2962     css::uno::Reference< css::awt::XWindow >                            xContainerWindow    = m_xContainerWindow   ;
2963     css::uno::Reference< css::lang::XMultiServiceFactory >              xFactory            = m_xFactory           ;
2964     css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >  xDragDropListener   = m_xDropTargetListener;
2965     css::uno::Reference< css::awt::XWindowListener >                    xWindowListener     ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
2966     css::uno::Reference< css::awt::XFocusListener >                     xFocusListener      ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
2967     css::uno::Reference< css::awt::XTopWindowListener >                 xTopWindowListener  ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
2968     aReadLock.unlock();
2969     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2970 
2971     if( xContainerWindow.is() == sal_True )
2972     {
2973         xContainerWindow->addWindowListener( xWindowListener);
2974         xContainerWindow->addFocusListener ( xFocusListener );
2975 
2976         css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
2977         if( xTopWindow.is() == sal_True )
2978         {
2979             xTopWindow->addTopWindowListener( xTopWindowListener );
2980 
2981             css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer( xFactory->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
2982             if( xTransfer.is() == sal_True )
2983 			{
2984                 css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget( xContainerWindow );
2985                 if( xDropTarget.is() == sal_True )
2986 				{
2987                     xDropTarget->addDropTargetListener( xDragDropListener );
2988 					xDropTarget->setActive( sal_True );
2989 				}
2990 			}
2991 		}
2992     }
2993 }
2994 
2995 //*****************************************************************************************************************
implts_stopWindowListening()2996 void Frame::implts_stopWindowListening()
2997 {
2998     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2999     // Sometimes used by dispose() => soft exceptions!
3000     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
3001 
3002     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3003     // Make snapshot of necessary member!
3004     ReadGuard aReadLock( m_aLock );
3005     css::uno::Reference< css::awt::XWindow >                            xContainerWindow    = m_xContainerWindow   ;
3006     css::uno::Reference< css::lang::XMultiServiceFactory >              xFactory            = m_xFactory           ;
3007     css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >  xDragDropListener   = m_xDropTargetListener;
3008     css::uno::Reference< css::awt::XWindowListener >                    xWindowListener     ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3009     css::uno::Reference< css::awt::XFocusListener >                     xFocusListener      ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3010     css::uno::Reference< css::awt::XTopWindowListener >                 xTopWindowListener  ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3011     aReadLock.unlock();
3012     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
3013 
3014     if( xContainerWindow.is() == sal_True )
3015     {
3016         xContainerWindow->removeWindowListener( xWindowListener);
3017         xContainerWindow->removeFocusListener ( xFocusListener );
3018 
3019         css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
3020         if( xTopWindow.is() == sal_True )
3021         {
3022             xTopWindow->removeTopWindowListener( xTopWindowListener );
3023 
3024             css::uno::Reference< css::awt::XDataTransferProviderAccess > xTransfer( xFactory->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
3025             if( xTransfer.is() == sal_True )
3026 			{
3027                 css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xTransfer->getDropTarget( xContainerWindow );
3028                 if( xDropTarget.is() == sal_True )
3029 				{
3030                     xDropTarget->removeDropTargetListener( xDragDropListener );
3031 					xDropTarget->setActive( sal_False );
3032 				}
3033 			}
3034         }
3035     }
3036 }
3037 
3038 /*-****************************************************************************************************//**
3039     @short      helper to force breaked close() request again
3040     @descr      If we self disagree with a close() request, and detect that all external locks are gone ...
3041                 then we must try to close this frame again.
3042 
3043     @seealso    XCloseable::close()
3044     @seealso    Frame::close()
3045     @seealso    Frame::removeActionLock()
3046     @seealso    Frame::resetActionLock()
3047     @seealso    m_bSelfClose
3048     @seealso    m_nExternalLockCount
3049 
3050     @threadsafe yes
3051     @modified   06.05.2002 09:31, as96863
3052 *//*-*****************************************************************************************************/
implts_checkSuicide()3053 void Frame::implts_checkSuicide()
3054 {
3055     /* SAFE */
3056     ReadGuard aReadLock(m_aLock);
3057     // in case of lock==0 and safed state of previous close() request m_bSelfClose
3058     // we must force close() again. Because we had disagreed with that before.
3059     sal_Bool bSuicide = (m_nExternalLockCount==0 && m_bSelfClose);
3060     m_bSelfClose = sal_False;
3061     aReadLock.unlock();
3062     /* } SAFE */
3063     // force close and deliver owner ship to source of possible throwed veto exception
3064     // Attention: Because this method isn't designed to throw such exception we must suppress
3065     // it for outside code!
3066     try
3067     {
3068         if (bSuicide)
3069             close(sal_True);
3070     }
3071     catch(const css::util::CloseVetoException&)
3072         {}
3073     catch(const css::lang::DisposedException&)
3074         {}
3075 }
3076 
3077 //_______________________________________________________________
3078 
3079 /** little helper to enable/disable the menu closer at the menubar of the given frame.
3080 
3081     @param  xFrame
3082             we use its layout manager to set/reset a special callback.
3083             Its existence regulate visibility of this closer item.
3084 
3085     @param  bState
3086                 <TRUE/> enable; <FALSE/> disable this state
3087  */
3088 
impl_setCloser(const css::uno::Reference<css::frame::XFrame> & xFrame,sal_Bool bState)3089 void Frame::impl_setCloser( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame ,
3090                             /*IN*/       sal_Bool                                   bState  )
3091 {
3092     // Note: If start module isn't installed - no closer has to be shown!
3093     if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE))
3094         return;
3095 
3096     try
3097     {
3098         css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY_THROW);
3099         css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
3100         xFrameProps->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
3101         css::uno::Reference< css::beans::XPropertySet > xLayoutProps(xLayoutManager, css::uno::UNO_QUERY_THROW);
3102         xLayoutProps->setPropertyValue(LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, css::uno::makeAny(bState));
3103     }
3104     catch(const css::uno::RuntimeException&)
3105         { throw; }
3106     catch(const css::uno::Exception&)
3107         {}
3108 }
3109 
3110 //_______________________________________________________________
3111 
3112 /** it checks, which of the top level task frames must have the special menu closer for
3113     switching to the backing window mode.
3114 
3115     It analyze the current list of visible top level frames. Only the last real document
3116     frame can have this symbol. Not the help frame nor the backing task itself.
3117     Here we do anything related to this closer. We remove it from the old frame and set it
3118     for the new one.
3119  */
3120 
impl_checkMenuCloser()3121 void Frame::impl_checkMenuCloser()
3122 {
3123     /* SAFE { */
3124     ReadGuard aReadLock(m_aLock);
3125 
3126     // only top frames, which are part of our desktop hierarchy, can
3127     // do so! By the way - we need the desktop instance to have access
3128     // to all other top level frames too.
3129     css::uno::Reference< css::frame::XDesktop >        xDesktop     (m_xParent, css::uno::UNO_QUERY);
3130     css::uno::Reference< css::frame::XFramesSupplier > xTaskSupplier(xDesktop , css::uno::UNO_QUERY);
3131     if ( !xDesktop.is() || !xTaskSupplier.is() )
3132         return;
3133 
3134     aReadLock.unlock();
3135     /* } SAFE */
3136 
3137     // analyze the list of current open tasks
3138     // Suppress search for other views to the same model ...
3139     // It's not needed here and can be very expensive.
3140     FrameListAnalyzer aAnalyzer(
3141         xTaskSupplier,
3142         this,
3143         FrameListAnalyzer::E_HIDDEN | FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
3144 
3145     // specify the new frame, which must have this special state ...
3146     css::uno::Reference< css::frame::XFrame > xNewCloserFrame;
3147 
3148     // -----------------------------
3149     // a)
3150     // If there exist ate least one other frame - there are two frames currently open.
3151     // But we can enable this closer only, if one of these two tasks includes the help module.
3152     // The "other frame" couldn't be the help. Because then it wouldn't be part of this "other list".
3153     // In such case it will be separated to the reference aAnalyzer.m_xHelp!
3154     // But we must check, if weself includes the help ...
3155     // Check aAnalyzer.m_bReferenceIsHelp!
3156     if (
3157         (aAnalyzer.m_lOtherVisibleFrames.getLength()==1)   &&
3158         (
3159             (aAnalyzer.m_bReferenceIsHelp  ) ||
3160             (aAnalyzer.m_bReferenceIsHidden)
3161         )
3162        )
3163     {
3164         // others[0] can't be the backing component!
3165         // Because it's set at the special member aAnalyzer.m_xBackingComponent ... :-)
3166         xNewCloserFrame = aAnalyzer.m_lOtherVisibleFrames[0];
3167     }
3168     else
3169     // -----------------------------
3170     // b)
3171     // There is no other frame ... means no other document frame. The help module
3172     // will be handled separately and must(!) be ignored here ... excepting weself includes the help.
3173     if (
3174         (aAnalyzer.m_lOtherVisibleFrames.getLength()==0) &&
3175         (!aAnalyzer.m_bReferenceIsHelp                 ) &&
3176         (!aAnalyzer.m_bReferenceIsHidden               ) &&
3177         (!aAnalyzer.m_bReferenceIsBacking              )
3178        )
3179     {
3180         xNewCloserFrame = this;
3181     }
3182 
3183     // Look for necessary actions ...
3184     // Only if the closer state must be moved from one frame to another one
3185     // or must be enabled/disabled at all.
3186     /* STATIC SAFE { */
3187     WriteGuard aStaticWriteLock(LockHelper::getGlobalLock());
3188     css::uno::Reference< css::frame::XFrame > xCloserFrame (m_xCloserFrame.get(), css::uno::UNO_QUERY);
3189     if (xCloserFrame!=xNewCloserFrame)
3190     {
3191         if (xCloserFrame.is())
3192             impl_setCloser(xCloserFrame, sal_False);
3193         if (xNewCloserFrame.is())
3194             impl_setCloser(xNewCloserFrame, sal_True);
3195         m_xCloserFrame = xNewCloserFrame;
3196     }
3197     aStaticWriteLock.unlock();
3198     /* } STATIC SAFE */
3199 }
3200 
3201 //_________________________________________________________________________________________________________________
3202 //	debug methods
3203 //_________________________________________________________________________________________________________________
3204 
3205 /*-----------------------------------------------------------------------------------------------------------------
3206 	The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
3207     we return "sal_True". (otherwise sal_False) This mechanism is used to throw an ASSERT!
3208 -----------------------------------------------------------------------------------------------------------------*/
3209 
3210 #ifdef ENABLE_ASSERTIONS
3211 
3212 //*****************************************************************************************************************
3213 // We don't accept null pointer or references!
implcp_ctor(const css::uno::Reference<css::lang::XMultiServiceFactory> & xFactory)3214 sal_Bool Frame::implcp_ctor( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
3215 {
3216 	return	(
3217 				( &xFactory		==	NULL		)	||
3218 				( xFactory.is()	==	sal_False	)
3219 			);
3220 }
3221 
3222 //*****************************************************************************************************************
3223 // Its allowed to reset the active frame membervariable with a NULL-css::uno::Reference but not with a NULL-pointer!
3224 // And we accept frames only! No tasks and desktops!
implcp_setActiveFrame(const css::uno::Reference<css::frame::XFrame> & xFrame)3225 sal_Bool Frame::implcp_setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame )
3226 {
3227 	return	(
3228                 ( &xFrame                                                                                   ==  NULL        )   ||
3229                 ( css::uno::Reference< css::frame::XDesktop >( xFrame, css::uno::UNO_QUERY ).is()           ==  sal_True    )
3230 			);
3231 }
3232 
3233 //*****************************************************************************************************************
implcp_addFrameActionListener(const css::uno::Reference<css::frame::XFrameActionListener> & xListener)3234 sal_Bool Frame::implcp_addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
3235 {
3236 	return	(
3237 				( &xListener		==	NULL		)	||
3238 				( xListener.is()	==	sal_False	)
3239 			);
3240 }
3241 
3242 //*****************************************************************************************************************
implcp_removeFrameActionListener(const css::uno::Reference<css::frame::XFrameActionListener> & xListener)3243 sal_Bool Frame::implcp_removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
3244 {
3245 	return	(
3246 				( &xListener		==	NULL		)	||
3247 				( xListener.is()	==	sal_False	)
3248 			);
3249 }
3250 
3251 //*****************************************************************************************************************
implcp_addEventListener(const css::uno::Reference<css::lang::XEventListener> & xListener)3252 sal_Bool Frame::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
3253 {
3254 	return	(
3255 				( &xListener		==	NULL		)	||
3256 				( xListener.is()	==	sal_False	)
3257 			);
3258 }
3259 
3260 //*****************************************************************************************************************
implcp_removeEventListener(const css::uno::Reference<css::lang::XEventListener> & xListener)3261 sal_Bool Frame::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
3262 {
3263 	return	(
3264 				( &xListener		==	NULL		)	||
3265 				( xListener.is()	==	sal_False	)
3266 			);
3267 }
3268 
3269 //*****************************************************************************************************************
implcp_windowResized(const css::awt::WindowEvent & aEvent)3270 sal_Bool Frame::implcp_windowResized( const css::awt::WindowEvent& aEvent )
3271 {
3272 	return	(
3273 				( &aEvent				==	NULL		)	||
3274 				( aEvent.Source.is()	==	sal_False	)
3275 			);
3276 }
3277 
3278 //*****************************************************************************************************************
implcp_focusGained(const css::awt::FocusEvent & aEvent)3279 sal_Bool Frame::implcp_focusGained( const css::awt::FocusEvent& aEvent )
3280 {
3281 	return	(
3282 				( &aEvent				==	NULL		)	||
3283 				( aEvent.Source.is()	==	sal_False	)
3284 			);
3285 }
3286 
3287 //*****************************************************************************************************************
implcp_windowActivated(const css::lang::EventObject & aEvent)3288 sal_Bool Frame::implcp_windowActivated( const css::lang::EventObject& aEvent )
3289 {
3290 	return	(
3291 				( &aEvent				==	NULL		)	||
3292 				( aEvent.Source.is()	==	sal_False	)
3293 			);
3294 }
3295 
3296 //*****************************************************************************************************************
implcp_windowDeactivated(const css::lang::EventObject & aEvent)3297 sal_Bool Frame::implcp_windowDeactivated( const css::lang::EventObject& aEvent )
3298 {
3299 	return	(
3300 				( &aEvent				==	NULL		)	||
3301 				( aEvent.Source.is()	==	sal_False	)
3302 			);
3303 }
3304 
3305 //*****************************************************************************************************************
implcp_disposing(const css::lang::EventObject & aEvent)3306 sal_Bool Frame::implcp_disposing( const css::lang::EventObject& aEvent )
3307 {
3308 	return	(
3309 				( &aEvent				==	NULL		)	||
3310 				( aEvent.Source.is()	==	sal_False	)
3311 			);
3312 }
3313 
3314 #endif	// #ifdef ENABLE_ASSERTIONS
3315 
3316 }	// namespace framework
3317