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