LCOV - code coverage report
Current view: top level - framework/source/services - desktop.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 374 545 68.6 %
Date: 2014-11-03 Functions: 56 73 76.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <services/desktop.hxx>
      21             : 
      22             : #include <loadenv/loadenv.hxx>
      23             : #include <loadenv/targethelper.hxx>
      24             : 
      25             : #include <helper/ocomponentaccess.hxx>
      26             : #include <helper/oframes.hxx>
      27             : #include <dispatch/dispatchprovider.hxx>
      28             : 
      29             : #include <dispatch/interceptionhelper.hxx>
      30             : #include <classes/taskcreator.hxx>
      31             : #include <threadhelp/transactionguard.hxx>
      32             : #include <general.h>
      33             : #include <properties.h>
      34             : 
      35             : #include <classes/resource.hrc>
      36             : #include <classes/fwkresid.hxx>
      37             : 
      38             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      39             : #include <com/sun/star/frame/FrameSearchFlag.hpp>
      40             : #include <com/sun/star/awt/XWindow.hpp>
      41             : #include <com/sun/star/awt/XWindowPeer.hpp>
      42             : #include <com/sun/star/awt/WindowDescriptor.hpp>
      43             : #include <com/sun/star/awt/WindowAttribute.hpp>
      44             : #include <com/sun/star/awt/PosSize.hpp>
      45             : #include <com/sun/star/util/XURLTransformer.hpp>
      46             : #include <com/sun/star/task/XInteractionAbort.hpp>
      47             : #include <com/sun/star/task/XInteractionApprove.hpp>
      48             : #include <com/sun/star/document/XInteractionFilterSelect.hpp>
      49             : #include <com/sun/star/task/ErrorCodeRequest.hpp>
      50             : #include <com/sun/star/ucb/InteractiveIOException.hpp>
      51             : #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
      52             : #include <com/sun/star/frame/XNotifyingDispatch.hpp>
      53             : #include <com/sun/star/frame/DispatchResultState.hpp>
      54             : #include <com/sun/star/lang/IllegalArgumentException.hpp>
      55             : #include <com/sun/star/lang/DisposedException.hpp>
      56             : #include <com/sun/star/util/XCloseable.hpp>
      57             : #include <com/sun/star/document/MacroExecMode.hpp>
      58             : #include <com/sun/star/document/UpdateDocMode.hpp>
      59             : #include <com/sun/star/frame/XTerminateListener2.hpp>
      60             : 
      61             : #include <comphelper/sequence.hxx>
      62             : #include <cppuhelper/supportsservice.hxx>
      63             : #include <vcl/svapp.hxx>
      64             : 
      65             : #include <tools/errinf.hxx>
      66             : #include <comphelper/extract.hxx>
      67             : 
      68             : namespace framework{
      69             : 
      70           0 : OUString SAL_CALL Desktop::getImplementationName()
      71             :     throw (css::uno::RuntimeException, std::exception)
      72             : {
      73           0 :     return OUString("com.sun.star.comp.framework.Desktop");
      74             : }
      75             : 
      76           2 : sal_Bool SAL_CALL Desktop::supportsService(OUString const & ServiceName)
      77             :     throw (css::uno::RuntimeException, std::exception)
      78             : {
      79           2 :     return cppu::supportsService(this, ServiceName);
      80             : }
      81             : 
      82           2 : css::uno::Sequence<OUString> SAL_CALL Desktop::getSupportedServiceNames()
      83             :     throw (css::uno::RuntimeException, std::exception)
      84             : {
      85           2 :     css::uno::Sequence< OUString > aSeq(1);
      86           2 :     aSeq[0] = OUString("com.sun.star.frame.Desktop");
      87           2 :     return aSeq;
      88             : }
      89             : 
      90         309 : void Desktop::constructorInit()
      91             : {
      92             :     // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
      93             :     // We hold member as reference ... not as pointer too!
      94             :     // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
      95             :     // But look on dispose() for right order of deinitialization.
      96         309 :     OFrames* pFramesHelper = new OFrames( this, &m_aChildTaskContainer );
      97         309 :     m_xFramesHelper = css::uno::Reference< css::frame::XFrames >( static_cast< ::cppu::OWeakObject* >(pFramesHelper), css::uno::UNO_QUERY );
      98             : 
      99             :     // Initialize a new dispatchhelper-object to handle dispatches.
     100             :     // We use these helper as slave for our interceptor helper ... not directly!
     101             :     // But he is event listener on THIS instance!
     102         309 :     DispatchProvider* pDispatchHelper = new DispatchProvider( m_xContext, this );
     103         309 :     css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
     104             : 
     105             :     // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
     106             :     // Set created dispatch provider as slowest slave of it.
     107             :     // Hold interception helper by reference only - not by pointer!
     108             :     // So it's easier to destroy it.
     109         309 :     InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
     110         309 :     m_xDispatchHelper = css::uno::Reference< css::frame::XDispatchProvider >( static_cast< ::cppu::OWeakObject* >(pInterceptionHelper), css::uno::UNO_QUERY );
     111             : 
     112         618 :     OUStringBuffer sUntitledPrefix (256);
     113         309 :     sUntitledPrefix.append      (FWK_RESSTR(STR_UNTITLED_DOCUMENT));
     114         309 :     sUntitledPrefix.appendAscii (" ");
     115             : 
     116         309 :     ::comphelper::NumberedCollection* pNumbers = new ::comphelper::NumberedCollection ();
     117         309 :     m_xTitleNumberGenerator = css::uno::Reference< css::frame::XUntitledNumbers >(static_cast< ::cppu::OWeakObject* >(pNumbers), css::uno::UNO_QUERY_THROW);
     118         309 :     pNumbers->setOwner          ( static_cast< ::cppu::OWeakObject* >(this) );
     119         309 :     pNumbers->setUntitledPrefix ( sUntitledPrefix.makeStringAndClear ()     );
     120             : 
     121             :     // Safe impossible cases
     122             :     // We can't work without this helper!
     123             :     SAL_WARN_IF( !m_xFramesHelper.is(), "fwk", "Desktop::Desktop(): Frames helper is not valid. XFrames, XIndexAccess and XElementAcces are not supported!");
     124             :     SAL_WARN_IF( !m_xDispatchHelper.is(), "fwk", "Desktop::Desktop(): Dispatch helper is not valid. XDispatch will not work correctly!" );
     125             : 
     126             :     // Enable object for real working!
     127             :     // Otherwise all calls will be rejected ...
     128         618 :     m_aTransactionManager.setWorkingMode( E_WORK );
     129         309 : }
     130             : 
     131             : /*-************************************************************************************************************
     132             :     @short      standard constructor to create instance by factory
     133             :     @descr      This constructor initialize a new instance of this class by valid factory,
     134             :                 and will be set valid values on his member and baseclasses.
     135             : 
     136             :     @attention  a)  Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
     137             :                     will get over this. (e.g. using of your reference as parameter to initialize some member)
     138             :                     Do such things in DEFINE_INIT_SERVICE() method, which is called automatically after your ctor!!!
     139             :                 b)  Baseclass OBroadcastHelper is a typedef in namespace cppu!
     140             :                     The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
     141             :                     If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
     142             :                     I don't know why! (other compiler not tested .. but it works!)
     143             : 
     144             :     @seealso    method DEFINE_INIT_SERVICE()
     145             : 
     146             :     @param      "xFactory" is the multi service manager, which create this instance.
     147             :                 The value must be different from NULL!
     148             :     @onerror    We throw an ASSERT in debug version or do nothing in relaese version.
     149             : *//*-*************************************************************************************************************/
     150         309 : Desktop::Desktop( const css::uno::Reference< css::uno::XComponentContext >& xContext )
     151             :         :   TransactionBase         (                                               )
     152             :         ,   Desktop_BASE            ( m_aMutex )
     153             :         ,   cppu::OPropertySetHelper( cppu::WeakComponentImplHelperBase::rBHelper   )
     154             :         // Init member
     155             :         ,   m_bIsTerminated         ( false                                     )   // see dispose() for further information!
     156             :         ,   m_xContext              ( xContext                                      )
     157             :         ,   m_aChildTaskContainer   (                                               )
     158             :         ,   m_aListenerContainer    ( m_aMutex )
     159             :         ,   m_xFramesHelper         (                                               )
     160             :         ,   m_xDispatchHelper       (                                               )
     161             :         ,   m_eLoadState            ( E_NOTSET                                      )
     162             :         ,   m_xLastFrame            (                                               )
     163             :         ,   m_aInteractionRequest   (                                               )
     164             :         ,   m_bSuspendQuickstartVeto( false                                     )
     165             :         ,   m_aCommandOptions       (                                               )
     166             :         ,   m_sName                 (                                               )
     167             :         ,   m_sTitle                (                                               )
     168             :         ,   m_xDispatchRecorderSupplier(                                            )
     169             :         ,   m_xPipeTerminator       (                                               )
     170             :         ,   m_xQuickLauncher        (                                               )
     171             :         ,   m_xSWThreadManager      (                                               )
     172             :         ,   m_xSfxTerminator        (                                               )
     173         309 :         ,   m_xTitleNumberGenerator (                                               )
     174             : {
     175         309 : }
     176             : 
     177             : /*-************************************************************************************************************
     178             :     @short      standard destructor
     179             :     @descr      This one do NOTHING! Use dispose() instaed of this.
     180             : 
     181             :     @seealso    method dispose()
     182             : *//*-*************************************************************************************************************/
     183         406 : Desktop::~Desktop()
     184             : {
     185             :     SAL_WARN_IF( !m_bIsTerminated, "fwk", "Desktop not terminated before being destructed" );
     186             :     SAL_WARN_IF( m_aTransactionManager.getWorkingMode()!=E_CLOSE, "fwk", "Desktop::~Desktop(): Who forgot to dispose this service?" );
     187         406 : }
     188             : 
     189      326275 : css::uno::Any SAL_CALL Desktop::queryInterface( const css::uno::Type& _rType ) throw(css::uno::RuntimeException, std::exception)
     190             : {
     191      326275 :     css::uno::Any aRet = Desktop_BASE::queryInterface( _rType );
     192      326275 :     if ( !aRet.hasValue() )
     193        1114 :         aRet = OPropertySetHelper::queryInterface( _rType );
     194      326275 :     return aRet;
     195             : }
     196             : 
     197          40 : css::uno::Sequence< css::uno::Type > SAL_CALL Desktop::getTypes(  ) throw(css::uno::RuntimeException, std::exception)
     198             : {
     199             :     return comphelper::concatSequences(
     200             :         Desktop_BASE::getTypes(),
     201             :         ::cppu::OPropertySetHelper::getTypes()
     202          40 :     );
     203             : }
     204             : 
     205         168 : sal_Bool SAL_CALL Desktop::terminate()
     206             :     throw( css::uno::RuntimeException, std::exception )
     207             : {
     208         168 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     209             : 
     210         336 :     SolarMutexClearableGuard aReadLock;
     211             : 
     212         336 :     css::uno::Reference< css::frame::XTerminateListener > xPipeTerminator    = m_xPipeTerminator;
     213         336 :     css::uno::Reference< css::frame::XTerminateListener > xQuickLauncher     = m_xQuickLauncher;
     214         336 :     css::uno::Reference< css::frame::XTerminateListener > xSWThreadManager   = m_xSWThreadManager;
     215         336 :     css::uno::Reference< css::frame::XTerminateListener > xSfxTerminator     = m_xSfxTerminator;
     216             : 
     217         336 :     css::lang::EventObject                                aEvent             ( static_cast< ::cppu::OWeakObject* >(this) );
     218         168 :     bool                                                  bAskQuickStart     = !m_bSuspendQuickstartVeto;
     219             : 
     220         168 :     aReadLock.clear();
     221             : 
     222             :     // Ask normal terminate listener. They could stop terminate without closing any open document.
     223         336 :     Desktop::TTerminateListenerList lCalledTerminationListener;
     224         168 :     bool                      bVeto = false;
     225         168 :     impl_sendQueryTerminationEvent(lCalledTerminationListener, bVeto);
     226         168 :     if ( bVeto )
     227             :     {
     228           0 :         impl_sendCancelTerminationEvent(lCalledTerminationListener);
     229           0 :         return sal_False;
     230             :     }
     231             : 
     232             :     // try to close all open frames.
     233             :     // Allow using of any UI ... because Desktop.terminate() was designed as UI functionality in the past.
     234         168 :     bool bAllowUI      = true;
     235         168 :     bool bFramesClosed = impl_closeFrames(bAllowUI);
     236         168 :     if ( ! bFramesClosed )
     237             :     {
     238           0 :         impl_sendCancelTerminationEvent(lCalledTerminationListener);
     239           0 :         return sal_False;
     240             :     }
     241             : 
     242             :     // Normal listener had no problem ...
     243             :     // all frames was closed ...
     244             :     // now it's time to ask our specialized listener.
     245             :     // They are handled these way because they wish to hinder the office on termination
     246             :     // but they wish also closing of all frames.
     247             : 
     248             :     // Note further:
     249             :     //    We shouldn't ask quicklauncher in case it was allowed from outside only.
     250             :     //    This is special trick to "ignore existing quick starter" for debug purposes.
     251             : 
     252             :     // Attention:
     253             :     // Order of alled listener is important !
     254             :     // some of them are harmless .-)
     255             :     // But some of them can be dangerous. E.g. it would be dangerous if we close our pipe
     256             :     // and dont terminate in real because another listener throws a veto exception .-)
     257             : 
     258         168 :     bool bTerminate = false;
     259             :     try
     260             :     {
     261         168 :         if(
     262         336 :             ( bAskQuickStart      ) &&
     263         168 :             ( xQuickLauncher.is() )
     264             :           )
     265             :         {
     266           0 :             xQuickLauncher->queryTermination( aEvent );
     267           0 :             lCalledTerminationListener.push_back( xQuickLauncher );
     268             :         }
     269             : 
     270         168 :         if ( xSWThreadManager.is() )
     271             :         {
     272           2 :             xSWThreadManager->queryTermination( aEvent );
     273           2 :             lCalledTerminationListener.push_back( xSWThreadManager );
     274             :         }
     275             : 
     276         168 :         if ( xPipeTerminator.is() )
     277             :         {
     278          96 :             xPipeTerminator->queryTermination( aEvent );
     279          96 :             lCalledTerminationListener.push_back( xPipeTerminator );
     280             :         }
     281             : 
     282         168 :         if ( xSfxTerminator.is() )
     283             :         {
     284         168 :             xSfxTerminator->queryTermination( aEvent );
     285         168 :             lCalledTerminationListener.push_back( xSfxTerminator );
     286             :         }
     287             : 
     288         168 :         bTerminate = true;
     289             :     }
     290           0 :     catch(const css::frame::TerminationVetoException&)
     291             :     {
     292           0 :         bTerminate = false;
     293             :     }
     294             : 
     295         168 :     if ( ! bTerminate )
     296           0 :         impl_sendCancelTerminationEvent(lCalledTerminationListener);
     297             :     else
     298             :     {
     299             :             // "Protect" us against dispose before terminate calls!
     300             :             // see dispose() for further information.
     301             :             /* SAFE AREA --------------------------------------------------------------------------------------- */
     302         168 :             SolarMutexClearableGuard aWriteLock;
     303         168 :             m_bIsTerminated = true;
     304         168 :             aWriteLock.clear();
     305             :             /* UNSAFE AREA ------------------------------------------------------------------------------------- */
     306             : 
     307         168 :         impl_sendNotifyTerminationEvent();
     308             : 
     309         168 :         if(
     310         336 :             ( bAskQuickStart      ) &&
     311         168 :             ( xQuickLauncher.is() )
     312             :           )
     313             :         {
     314           0 :             xQuickLauncher->notifyTermination( aEvent );
     315             :         }
     316             : 
     317         168 :         if ( xSWThreadManager.is() )
     318           2 :             xSWThreadManager->notifyTermination( aEvent );
     319             : 
     320         168 :         if ( xPipeTerminator.is() )
     321          96 :             xPipeTerminator->notifyTermination( aEvent );
     322             : 
     323             :         // Must be really the last listener to be called.
     324             :         // Because it shutdown the whole process asynchronous !
     325         168 :         if ( xSfxTerminator.is() )
     326         168 :             xSfxTerminator->notifyTermination( aEvent );
     327             :     }
     328             : 
     329         336 :     return bTerminate;
     330             : }
     331             : 
     332             : namespace
     333             : {
     334             :     class QuickstartSuppressor
     335             :     {
     336             :         Desktop* const m_pDesktop;
     337             :         css::uno::Reference< css::frame::XTerminateListener > m_xQuickLauncher;
     338             :         public:
     339           0 :             QuickstartSuppressor(Desktop* const pDesktop, css::uno::Reference< css::frame::XTerminateListener > xQuickLauncher)
     340             :                 : m_pDesktop(pDesktop)
     341           0 :                 , m_xQuickLauncher(xQuickLauncher)
     342             :             {
     343             :                 SAL_INFO("fwk.desktop", "temporary removing Quickstarter");
     344           0 :                 if(m_xQuickLauncher.is())
     345           0 :                     m_pDesktop->removeTerminateListener(m_xQuickLauncher);
     346           0 :             }
     347           0 :             ~QuickstartSuppressor()
     348           0 :             {
     349             :                 SAL_INFO("fwk.desktop", "readding Quickstarter");
     350           0 :                 if(m_xQuickLauncher.is())
     351           0 :                     m_pDesktop->addTerminateListener(m_xQuickLauncher);
     352           0 :             }
     353             :     };
     354             : }
     355             : 
     356           0 : bool SAL_CALL Desktop::terminateQuickstarterToo()
     357             :     throw( css::uno::RuntimeException )
     358             : {
     359           0 :     QuickstartSuppressor aQuickstartSuppressor(this, m_xQuickLauncher);
     360           0 :     return terminate();
     361             : }
     362             : 
     363        1821 : void SAL_CALL Desktop::addTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener )
     364             :     throw( css::uno::RuntimeException, std::exception )
     365             : {
     366        1821 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     367             : 
     368        3241 :     css::uno::Reference< css::lang::XServiceInfo > xInfo( xListener, css::uno::UNO_QUERY );
     369        1821 :     if ( xInfo.is() )
     370             :     {
     371         421 :         OUString sImplementationName = xInfo->getImplementationName();
     372             : 
     373         441 :         SolarMutexGuard g;
     374             : 
     375         421 :         if( sImplementationName == "com.sun.star.comp.sfx2.SfxTerminateListener" )
     376             :         {
     377         303 :             m_xSfxTerminator = xListener;
     378         303 :             return;
     379             :         }
     380         118 :         if( sImplementationName == "com.sun.star.comp.OfficeIPCThreadController" )
     381             :         {
     382          96 :             m_xPipeTerminator = xListener;
     383          96 :             return;
     384             :         }
     385          22 :         if( sImplementationName == "com.sun.star.comp.desktop.QuickstartWrapper" )
     386             :         {
     387           0 :             m_xQuickLauncher = xListener;
     388           0 :             return;
     389             :         }
     390          22 :         if( sImplementationName == "com.sun.star.util.comp.FinalThreadManager" )
     391             :         {
     392           2 :             m_xSWThreadManager = xListener;
     393           2 :             return;
     394          20 :         }
     395             :     }
     396             : 
     397             :     // No lock required ... container is threadsafe by itself.
     398        2840 :     m_aListenerContainer.addInterface( cppu::UnoType<css::frame::XTerminateListener>::get(), xListener );
     399             : }
     400             : 
     401        2476 : void SAL_CALL Desktop::removeTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener )
     402             :     throw( css::uno::RuntimeException, std::exception )
     403             : {
     404        2476 :     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
     405             : 
     406        4784 :     css::uno::Reference< css::lang::XServiceInfo > xInfo( xListener, css::uno::UNO_QUERY );
     407        2476 :     if ( xInfo.is() )
     408             :     {
     409         184 :         OUString sImplementationName = xInfo->getImplementationName();
     410             : 
     411         200 :         SolarMutexGuard g;
     412             : 
     413         184 :         if( sImplementationName == "com.sun.star.comp.sfx2.SfxTerminateListener" )
     414             :         {
     415         168 :             m_xSfxTerminator.clear();
     416         168 :             return;
     417             :         }
     418             : 
     419          16 :         if( sImplementationName == "com.sun.star.comp.OfficeIPCThreadController" )
     420             :         {
     421           0 :             m_xPipeTerminator.clear();
     422           0 :             return;
     423             :         }
     424             : 
     425          16 :         if( sImplementationName == "com.sun.star.comp.desktop.QuickstartWrapper" )
     426             :         {
     427           0 :             m_xQuickLauncher.clear();
     428           0 :             return;
     429             :         }
     430             : 
     431          16 :         if( sImplementationName == "com.sun.star.util.comp.FinalThreadManager" )
     432             :         {
     433           0 :             m_xSWThreadManager.clear();
     434           0 :             return;
     435          16 :         }
     436             :     }
     437             : 
     438             :     // No lock required ... container is threadsafe by itself.
     439        4616 :     m_aListenerContainer.removeInterface( cppu::UnoType<css::frame::XTerminateListener>::get(), xListener );
     440             : }
     441             : 
     442             : /*-************************************************************************************************************
     443             :     @interface  XDesktop
     444             :     @short      get access to create enumerations of all current components
     445             :     @descr      You will be the owner of the returned object and must delete it if you don't use it again.
     446             : 
     447             :     @seealso    class TasksAccess
     448             :     @seealso    class TasksEnumeration
     449             :     @return     A reference to an XEnumerationAccess-object.
     450             : 
     451             :     @onerror    We return a null-reference.
     452             :     @threadsafe yes
     453             : *//*-*************************************************************************************************************/
     454         170 : css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL Desktop::getComponents() throw( css::uno::RuntimeException, std::exception )
     455             : {
     456             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     457             :     // Register transaction and reject wrong calls.
     458         170 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     459             : 
     460             :     // We use a helper class OComponentAccess to have access on all child components.
     461             :     // Create it on demand and return it as a reference.
     462         170 :     OComponentAccess* pAccess = new OComponentAccess( this );
     463         170 :     css::uno::Reference< css::container::XEnumerationAccess > xAccess( static_cast< ::cppu::OWeakObject* >(pAccess), css::uno::UNO_QUERY );
     464         170 :     return xAccess;
     465             : }
     466             : 
     467             : /*-************************************************************************************************************
     468             :     @interface  XDesktop
     469             :     @short      return the current active component
     470             :     @descr      The most current component is the window, model or the controller of the current active frame.
     471             : 
     472             :     @seealso    method getCurrentFrame()
     473             :     @seealso    method impl_getFrameComponent()
     474             :     @return     A reference to the component.
     475             : 
     476             :     @onerror    We return a null-reference.
     477             :     @threadsafe yes
     478             : *//*-*************************************************************************************************************/
     479           0 : css::uno::Reference< css::lang::XComponent > SAL_CALL Desktop::getCurrentComponent() throw( css::uno::RuntimeException, std::exception )
     480             : {
     481             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     482             :     // Register transaction and reject wrong calls.
     483           0 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     484             : 
     485             :     // Set return value if method failed.
     486           0 :     css::uno::Reference< css::lang::XComponent > xComponent;
     487             : 
     488             :     // Get reference to current frame ...
     489             :     // ... get component of this frame ... (It can be the window, the model or the controller.)
     490             :     // ... and return the result.
     491           0 :     css::uno::Reference< css::frame::XFrame > xCurrentFrame = getCurrentFrame();
     492           0 :     if( xCurrentFrame.is() )
     493             :     {
     494           0 :         xComponent = impl_getFrameComponent( xCurrentFrame );
     495             :     }
     496           0 :     return xComponent;
     497             : }
     498             : 
     499             : /*-************************************************************************************************************
     500             :     @interface  XDesktop
     501             :     @short      return the current active frame in hierarchy
     502             :     @descr      There can be more than one different active paths in our frame hierarchy. But only one of them
     503             :                 could be the most active frame (normal he has the focus).
     504             :                 Don't mix it with getActiveFrame()! That will return our current active frame, which must be
     505             :                 a direct child of us and should be a part(!) of an active path.
     506             : 
     507             :     @seealso    method getActiveFrame()
     508             :     @return     A valid reference, if there is an active frame.
     509             :                 A null reference , otherwise.
     510             : 
     511             :     @onerror    We return a null reference.
     512             :     @threadsafe yes
     513             : *//*-*************************************************************************************************************/
     514        2014 : css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::getCurrentFrame() throw( css::uno::RuntimeException, std::exception )
     515             : {
     516             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     517             :     // Register transaction and reject wrong calls.
     518        2014 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     519             : 
     520             :     // Start search with our direct active frame (if it exist!).
     521             :     // Search on his children for other active frames too.
     522             :     // Stop if no one could be found and return last of found ones.
     523        4028 :     css::uno::Reference< css::frame::XFramesSupplier > xLast = css::uno::Reference< css::frame::XFramesSupplier >( getActiveFrame(), css::uno::UNO_QUERY );
     524        2014 :     if( xLast.is() )
     525             :     {
     526         584 :         css::uno::Reference< css::frame::XFramesSupplier > xNext = css::uno::Reference< css::frame::XFramesSupplier >( xLast->getActiveFrame(), css::uno::UNO_QUERY );
     527        1168 :         while( xNext.is() )
     528             :         {
     529           0 :             xLast = xNext;
     530           0 :             xNext = css::uno::Reference< css::frame::XFramesSupplier >( xNext->getActiveFrame(), css::uno::UNO_QUERY );
     531         584 :         }
     532             :     }
     533        4028 :     return css::uno::Reference< css::frame::XFrame >( xLast, css::uno::UNO_QUERY );
     534             : }
     535             : 
     536             : /*-************************************************************************************************************
     537             :     @interface  XComponentLoader
     538             :     @short      try to load given URL into a task
     539             :     @descr      You can give us some information about the content, which you will load into a frame.
     540             :                 We search or create this target for you, make a type detection of given URL and try to load it.
     541             :                 As result of this operation we return the new created component or nothing, if loading failed.
     542             :     @param      "sURL"              , URL, which represant the content
     543             :     @param      "sTargetFrameName"  , name of target frame or special value like "_self", "_blank" ...
     544             :     @param      "nSearchFlags"      , optional arguments for frame search, if target isn't a special one
     545             :     @param      "lArguments"        , optional arguments for loading
     546             :     @return     A valid component reference, if loading was successfully.
     547             :                 A null reference otherwise.
     548             : 
     549             :     @onerror    We return a null reference.
     550             :     @threadsafe yes
     551             : *//*-*************************************************************************************************************/
     552        5542 : css::uno::Reference< css::lang::XComponent > SAL_CALL Desktop::loadComponentFromURL( const OUString&                                 sURL            ,
     553             :                                                                                      const OUString&                                 sTargetFrameName,
     554             :                                                                                            sal_Int32                                        nSearchFlags    ,
     555             :                                                                                      const css::uno::Sequence< css::beans::PropertyValue >& lArguments      ) throw(    css::io::IOException                ,
     556             :                                                                                                                                                                         css::lang::IllegalArgumentException ,
     557             :                                                                                                                                                                         css::uno::RuntimeException, std::exception          )
     558             : {
     559             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     560             :     // Register transaction and reject wrong calls.
     561        5542 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     562             :     SAL_INFO( "fwk.desktop", "framework (as96863) ::Desktop::loadComponentFromURL" );
     563             : 
     564       11084 :     css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
     565             : 
     566             :     SAL_INFO( "fwk.desktop", "PERFORMANCE - Desktop::loadComponentFromURL()" );
     567       11084 :     return LoadEnv::loadComponentFromURL(xThis, m_xContext, sURL, sTargetFrameName, nSearchFlags, lArguments);
     568             : }
     569             : 
     570             : /*-************************************************************************************************************
     571             :     @interface  XTasksSupplier
     572             :     @short      get access to create enumerations of our taskchildren
     573             :     @descr      Direct children of desktop are tasks everytime.
     574             :                 Call these method to could create enumerations of it.
     575             : 
     576             : But; Don't forget - you will be the owner of returned object and must release it!
     577             :                 We use a helper class to implement the access interface. They hold a weakreference to us.
     578             :                 It can be, that the desktop is dead - but not your tasksaccess-object! Then they will do nothing!
     579             :                 You can't create enumerations then.
     580             : 
     581             :     @attention  Normally we don't need any lock here. We don't work on internal member!
     582             : 
     583             :     @seealso    class TasksAccess
     584             :     @return     A reference to an accessobject, which can create enumerations of our childtasks.
     585             : 
     586             :     @onerror    A null reference is returned.
     587             :     @threadsafe yes
     588             : *//*-*************************************************************************************************************/
     589           0 : css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL Desktop::getTasks() throw( css::uno::RuntimeException, std::exception )
     590             : {
     591             :     SAL_INFO("fwk", "Desktop::getTasks(): Use of obsolete interface XTaskSupplier");
     592           0 :     return NULL;
     593             : }
     594             : 
     595             : /*-************************************************************************************************************
     596             :     @interface  XTasksSupplier
     597             :     @short      return current active task of our direct children
     598             :     @descr      Desktop children are tasks only ! If we have an active path from desktop
     599             :                 as top to any frame on bottom, we must have an active direct child. His reference is returned here.
     600             : 
     601             :     @attention  a)  Do not confuse it with getCurrentFrame()! The current frame don't must one of our direct children.
     602             :                     It can be every frame in subtree and must have the focus (Is the last one of an active path!).
     603             :                 b)  We don't need any lock here. Our container is threadsafe himself and live, if we live!
     604             : 
     605             :     @seealso    method getCurrentFrame()
     606             :     @return     A reference to our current active taskchild.
     607             : 
     608             :     @onerror    A null reference is returned.
     609             :     @threadsafe yes
     610             : *//*-*************************************************************************************************************/
     611           0 : css::uno::Reference< css::frame::XTask > SAL_CALL Desktop::getActiveTask() throw( css::uno::RuntimeException, std::exception )
     612             : {
     613             :     SAL_INFO("fwk", "Desktop::getActiveTask(): Use of obsolete interface XTaskSupplier");
     614           0 :     return NULL;
     615             : }
     616             : 
     617             : /*-************************************************************************************************************
     618             :     @interface  XDispatchProvider
     619             :     @short      search a dispatcher for given URL
     620             :     @descr      We use a helper implementation (class DispatchProvider) to do so.
     621             :                 So we don't must implement this algorithm twice!
     622             : 
     623             :     @attention  We don't need any lock here. Our helper is threadsafe himself and live, if we live!
     624             : 
     625             :     @seealso    class DispatchProvider
     626             : 
     627             :     @param      "aURL"              , URL to dispatch
     628             :     @param      "sTargetFrameName"  , name of target frame, who should dispatch these URL
     629             :     @param      "nSearchFlags"      , flags to regulate the search
     630             :     @param      "lQueries"          , list of queryDispatch() calls!
     631             :     @return     A reference or list of founded dispatch objects for these URL.
     632             : 
     633             :     @onerror    A null reference is returned.
     634             :     @threadsafe yes
     635             : *//*-*************************************************************************************************************/
     636         202 : css::uno::Reference< css::frame::XDispatch > SAL_CALL Desktop::queryDispatch( const css::util::URL&  aURL             ,
     637             :                                                                               const OUString& sTargetFrameName ,
     638             :                                                                                     sal_Int32        nSearchFlags     ) throw( css::uno::RuntimeException, std::exception )
     639             : {
     640         202 :     const char UNO_PROTOCOL[] = ".uno:";
     641             : 
     642             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     643             :     // Register transaction and reject wrong calls.
     644         202 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     645             : 
     646             :     // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
     647             :     // in our hash map. All other protocols are stored with the protocol part.
     648         404 :     OUString aCommand( aURL.Main );
     649         202 :     if ( aURL.Protocol.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL, sizeof( UNO_PROTOCOL )-1 ))
     650         202 :         aCommand = aURL.Path;
     651             : 
     652             :     // Make boost::unordered_map lookup if the current URL is in the disabled list
     653         202 :     if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
     654           0 :         return css::uno::Reference< css::frame::XDispatch >();
     655             :     else
     656             :     {
     657             :         // We use a helper to support these interface and an interceptor mechanism.
     658             :         // Our helper is threadsafe by himself!
     659         202 :         return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
     660         202 :     }
     661             : }
     662             : 
     663           2 : css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL Desktop::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lQueries ) throw( css::uno::RuntimeException, std::exception )
     664             : {
     665             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     666             :     // Register transaction and reject wrong calls.
     667           2 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     668             : 
     669           2 :     return m_xDispatchHelper->queryDispatches( lQueries );
     670             : }
     671             : 
     672             : /*-************************************************************************************************************
     673             :     @interface  XDipsatchProviderInterception
     674             :     @short      supports registration/deregistration of interception objects, which
     675             :                 are interested on special dispatches.
     676             : 
     677             :     @descr      Its really provided by an internal helper, which is used inside the dispatch api too.
     678             :     @param      xInterceptor
     679             :                 the interceptor object, which wish to be (de)registered.
     680             : 
     681             :     @threadsafe yes
     682             : *//*-*************************************************************************************************************/
     683           2 : void SAL_CALL Desktop::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
     684             :     throw( css::uno::RuntimeException, std::exception)
     685             : {
     686           2 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     687             : 
     688           4 :     css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
     689           4 :     xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
     690           2 : }
     691             : 
     692           2 : void SAL_CALL Desktop::releaseDispatchProviderInterceptor ( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
     693             :     throw( css::uno::RuntimeException, std::exception)
     694             : {
     695           2 :     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
     696             : 
     697           4 :     css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
     698           4 :     xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
     699           2 : }
     700             : 
     701             : /*-************************************************************************************************************
     702             :     @interface  XFramesSupplier
     703             :     @short      return access to append or remove children on desktop
     704             :     @descr      We don't implement these interface directly. We use a helper class to do this.
     705             :                 If you wish to add or delete children to/from the container, call these method to get
     706             :                 a reference to the helper.
     707             : 
     708             :     @attention  Helper is threadsafe himself. So we don't need any lock here.
     709             : 
     710             :     @seealso    class OFrames
     711             :     @return     A reference to the helper.
     712             : 
     713             :     @onerror    A null reference is returned.
     714             :     @threadsafe yes
     715             : *//*-*************************************************************************************************************/
     716       47090 : css::uno::Reference< css::frame::XFrames > SAL_CALL Desktop::getFrames() throw( css::uno::RuntimeException, std::exception )
     717             : {
     718             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     719             :     // Register transaction and reject wrong calls.
     720       47090 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     721             : 
     722       47090 :     return m_xFramesHelper;
     723             : }
     724             : 
     725             : /*-************************************************************************************************************
     726             :     @interface  XFramesSupplier
     727             :     @short      set/get the current active child frame
     728             :     @descr      It must be a task. Direct children of desktop are tasks only! No frames are accepted.
     729             :                 We don't save this information directly in this class. We use our container-helper
     730             :                 to do that.
     731             : 
     732             :     @attention  Helper is threadsafe himself. So we don't need any lock here.
     733             : 
     734             :     @seealso    class OFrameContainer
     735             : 
     736             :     @param      "xFrame", new active frame (must be valid!)
     737             :     @return     A reference to our current active childtask, if anyone exist.
     738             : 
     739             :     @onerror    A null reference is returned.
     740             :     @threadsafe yes
     741             : *//*-*************************************************************************************************************/
     742        5043 : void SAL_CALL Desktop::setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException, std::exception )
     743             : {
     744             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     745             :     // Register transaction and reject wrong calls.
     746        5043 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     747             : 
     748             :     // Get old active frame first.
     749             :     // If nothing will change - do nothing!
     750             :     // Otherwise set new active frame ...
     751             :     // and deactivate last frame.
     752             :     // It's necessary for our FrameActionEvent listener on a frame!
     753       10086 :     css::uno::Reference< css::frame::XFrame > xLastActiveChild = m_aChildTaskContainer.getActive();
     754        5043 :     if( xLastActiveChild != xFrame )
     755             :     {
     756        5032 :         m_aChildTaskContainer.setActive( xFrame );
     757        5032 :         if( xLastActiveChild.is() )
     758             :         {
     759          42 :             xLastActiveChild->deactivate();
     760             :         }
     761        5043 :     }
     762        5043 : }
     763             : 
     764        9034 : css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::getActiveFrame() throw( css::uno::RuntimeException, std::exception )
     765             : {
     766             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
     767             :     // Register transaction and reject wrong calls.
     768        9034 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
     769             : 
     770        9034 :     return m_aChildTaskContainer.getActive();
     771             : }
     772             : 
     773             : /*
     774             :     @interface  XFrame
     775             :     @short      non implemented methods!
     776             :     @descr      Some method make no sense for our desktop! He has no window or parent or ...
     777             :                 So we should implement it empty and warn programmer, if he use it!
     778             : */
     779           2 : void SAL_CALL Desktop::initialize( const css::uno::Reference< css::awt::XWindow >& ) throw( css::uno::RuntimeException, std::exception )
     780             : {
     781           2 : }
     782             : 
     783        5566 : css::uno::Reference< css::awt::XWindow > SAL_CALL Desktop::getContainerWindow() throw( css::uno::RuntimeException, std::exception )
     784             : {
     785        5566 :     return css::uno::Reference< css::awt::XWindow >();
     786             : }
     787             : 
     788           0 : void SAL_CALL Desktop::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& /*xCreator*/ ) throw( css::uno::RuntimeException, std::exception )
     789             : {
     790           0 : }
     791             : 
     792           0 : css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Desktop::getCreator() throw( css::uno::RuntimeException, std::exception )
     793             : {
     794           0 :     return css::uno::Reference< css::frame::XFramesSupplier >();
     795             : }
     796             : 
     797           4 : OUString SAL_CALL Desktop::getName() throw( css::uno::RuntimeException, std::exception )
     798             : {
     799           4 :     SolarMutexGuard g;
     800           4 :     return m_sName;
     801             : }
     802             : 
     803           2 : void SAL_CALL Desktop::setName( const OUString& sName ) throw( css::uno::RuntimeException, std::exception )
     804             : {
     805           2 :     SolarMutexGuard g;
     806           2 :     m_sName = sName;
     807           2 : }
     808             : 
     809           2 : sal_Bool SAL_CALL Desktop::isTop() throw( css::uno::RuntimeException, std::exception )
     810             : {
     811           2 :     return sal_True;
     812             : }
     813             : 
     814        5044 : void SAL_CALL Desktop::activate() throw( css::uno::RuntimeException, std::exception )
     815             : {
     816             :     // Desktop is activae always ... but sometimes our frames try to activate
     817             :     // the complete path from bottom to top ... And our desktop is the topest frame :-(
     818             :     // So - please don't show any assertions here. Do nothing!
     819        5044 : }
     820             : 
     821           6 : void SAL_CALL Desktop::deactivate() throw( css::uno::RuntimeException, std::exception )
     822             : {
     823             :     // Desktop is activae always ... but sometimes our frames try to deactivate
     824             :     // the complete path from bottom to top ... And our desktop is the topest frame :-(
     825             :     // So - please don't show any assertions here. Do nothing!
     826           6 : }
     827             : 
     828           2 : sal_Bool SAL_CALL Desktop::isActive() throw( css::uno::RuntimeException, std::exception )
     829             : {
     830           2 :     return sal_True;
     831             : }
     832             : 
     833           2 : sal_Bool SAL_CALL Desktop::setComponent( const css::uno::Reference< css::awt::XWindow >&       /*xComponentWindow*/ ,
     834             :                                          const css::uno::Reference< css::frame::XController >& /*xController*/      ) throw( css::uno::RuntimeException, std::exception )
     835             : {
     836           2 :     return sal_False;
     837             : }
     838             : 
     839           6 : css::uno::Reference< css::awt::XWindow > SAL_CALL Desktop::getComponentWindow() throw( css::uno::RuntimeException, std::exception )
     840             : {
     841           6 :     return css::uno::Reference< css::awt::XWindow >();
     842             : }
     843             : 
     844           6 : css::uno::Reference< css::frame::XController > SAL_CALL Desktop::getController() throw( css::uno::RuntimeException, std::exception )
     845             : {
     846           6 :     return css::uno::Reference< css::frame::XController >();
     847             : }
     848             : 
     849           4 : void SAL_CALL Desktop::contextChanged() throw( css::uno::RuntimeException, std::exception )
     850             : {
     851           4 : }
     852             : 
     853           2 : void SAL_CALL Desktop::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& ) throw( css::uno::RuntimeException, std::exception )
     854             : {
     855           2 : }
     856             : 
     857             : //   css::frame::XFrame
     858           2 : void SAL_CALL Desktop::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& ) throw( css::uno::RuntimeException, std::exception )
     859             : {
     860           2 : }
     861             : 
     862             : /*-************************************************************************************************************
     863             :     @interface  XFrame
     864             :     @short      try to find a frame with special parameters
     865             :     @descr      This method searches for a frame with the specified name.
     866             :                 Frames may contain other frames (e.g. a frameset) and may
     867             :                 be contained in other frames. This hierarchy is searched by
     868             :                 this method.
     869             :                 First some special names are taken into account, i.e. "",
     870             :                 "_self", "_top", "_parent" etc. The FrameSearchFlags are ignored
     871             :                 when comparing these names with aTargetFrameName, further steps are
     872             :                 controlled by the FrameSearchFlags. If allowed, the name of the frame
     873             :                 itself is compared with the desired one, then ( again if allowed )
     874             :                 the method findFrame is called for all children of the frame.
     875             :                 If no Frame with the given name is found until the top frames container,
     876             :                 a new top Frame is created, if this is allowed by a special
     877             :                 FrameSearchFlag. The new Frame also gets the desired name.
     878             :                 We use a helper to get right search direction and react in a right manner.
     879             : 
     880             :     @seealso    class TargetFinder
     881             : 
     882             :     @param      "sTargetFrameName"  , name of searched frame
     883             :     @param      "nSearchFlags"      , flags to regulate search
     884             :     @return     A reference to an existing frame in hierarchy, if it exist.
     885             : 
     886             :     @onerror    A null reference is returned.
     887             :     @threadsafe yes
     888             : *//*-*************************************************************************************************************/
     889        5570 : css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::findFrame( const OUString& sTargetFrameName ,
     890             :                                                                              sal_Int32        nSearchFlags     ) throw( css::uno::RuntimeException, std::exception )
     891             : {
     892        5570 :     css::uno::Reference< css::frame::XFrame > xTarget;
     893             : 
     894             :     // 0) Ignore wrong parameter!
     895             :     //    We don't support search for following special targets.
     896             :     //    If we reject this requests - we mustnt check for such names
     897             :     //    in following code again and again. If we do not so -wrong
     898             :     //    search results can occur!
     899             : 
     900       11140 :     if (
     901       33420 :         (sTargetFrameName==SPECIALTARGET_DEFAULT  )   ||    // valid for dispatches - not for findFrame()!
     902       27850 :         (sTargetFrameName==SPECIALTARGET_MENUBAR  )   ||    // valid for dispatches - not for findFrame()!
     903       44560 :         (sTargetFrameName==SPECIALTARGET_PARENT   )   ||    // we have no parent by definition
     904       16710 :         (sTargetFrameName==SPECIALTARGET_BEAMER   )         // beamer frames are allowed as child of tasks only -
     905             :                                                             // and they exist more than ones. We have no idea which our sub tasks is the right one
     906             :        )
     907             :     {
     908           0 :         return NULL;
     909             :     }
     910             : 
     911             :     // I) check for special defined targets first which must be handled exclusive.
     912             :     //    force using of "if() else if() ..."
     913             : 
     914             :     // I.I) "_blank"
     915             :     //  create a new task as child of this desktop instance
     916             :     //  Note: Used helper TaskCreator use us automatically ...
     917             : 
     918        5570 :     if ( sTargetFrameName==SPECIALTARGET_BLANK )
     919             :     {
     920        5556 :         TaskCreator aCreator( m_xContext );
     921        5556 :         xTarget = aCreator.createTask(sTargetFrameName,false);
     922             :     }
     923             : 
     924             :     // I.II) "_top"
     925             :     //  We are top by definition
     926             : 
     927          14 :     else if ( sTargetFrameName==SPECIALTARGET_TOP )
     928             :     {
     929           0 :         xTarget = this;
     930             :     }
     931             : 
     932             :     // I.III) "_self", ""
     933             :     //  This mean this "frame" in every case.
     934             : 
     935          28 :     else if (
     936          54 :              ( sTargetFrameName==SPECIALTARGET_SELF ) ||
     937          12 :              ( sTargetFrameName.isEmpty()           )
     938             :             )
     939             :     {
     940           2 :         xTarget = this;
     941             :     }
     942             : 
     943             :     else
     944             :     {
     945             : 
     946             :         // II) otherwise use optional given search flags
     947             :         //  force using of combinations of such flags. means no "else" part of use if() statements.
     948             :         //  But we ust break further searches if target was already found.
     949             :         //  Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
     950             :         //  TASK and CREATE are handled special.
     951             :         //  But note: Such flags are not valid for the desktop - especialy SIBLINGS or PARENT.
     952             : 
     953             :         // II.I) SELF
     954             :         //  Check for right name. If it's the searched one return ourself - otherwise
     955             :         //  ignore this flag.
     956             : 
     957          12 :         if (
     958          24 :             (nSearchFlags &  css::frame::FrameSearchFlag::SELF)  &&
     959          12 :             (m_sName == sTargetFrameName)
     960             :            )
     961             :         {
     962           0 :             xTarget = this;
     963             :         }
     964             : 
     965             :         // II.II) TASKS
     966             :         //  This is a special flag. Normally it regulate search inside tasks and forbid access to parent trees.
     967             :         //  But the desktop exists outside such task trees. They are our sub trees. So the desktop implement
     968             :         //  a special feature: We use it to start search on our direct children only. That means we supress
     969             :         //  search on ALL child frames. May that can be useful to get access on opened document tasks
     970             :         //  only without filter out all non really required sub frames ...
     971             :         //  Used helper method on our container doesn't create any frame - it's a search only.
     972             : 
     973          12 :         if (
     974          24 :             ( ! xTarget.is()                                  ) &&
     975          12 :             (nSearchFlags & css::frame::FrameSearchFlag::TASKS)
     976             :            )
     977             :         {
     978          12 :             xTarget = m_aChildTaskContainer.searchOnDirectChildrens(sTargetFrameName);
     979             :         }
     980             : 
     981             :         // II.III) CHILDREN
     982             :         //  Search on all children for the given target name.
     983             :         //  An empty name value can't occur here - because it must be already handled as "_self"
     984             :         //  before. Used helper function of container doesn't create any frame.
     985             :         //  It makes a deep search only.
     986             : 
     987          12 :         if (
     988          20 :             ( ! xTarget.is()                                     ) &&
     989           8 :             (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
     990             :            )
     991             :         {
     992           8 :             xTarget = m_aChildTaskContainer.searchOnAllChildrens(sTargetFrameName);
     993             :         }
     994             : 
     995             :         // II.IV) CREATE
     996             :         //  If we haven't found any valid target frame by using normal flags - but user allowed us to create
     997             :         //  a new one ... we should do that. Used TaskCreator use us automatically as parent!
     998             : 
     999          12 :         if (
    1000          20 :             ( ! xTarget.is()                                   )    &&
    1001           8 :             (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
    1002             :            )
    1003             :         {
    1004           8 :             TaskCreator aCreator( m_xContext );
    1005           8 :             xTarget = aCreator.createTask(sTargetFrameName,false);
    1006             :         }
    1007             :     }
    1008             : 
    1009        5570 :     return xTarget;
    1010             : }
    1011             : 
    1012         305 : void SAL_CALL Desktop::disposing()
    1013             :     throw( css::uno::RuntimeException )
    1014             : {
    1015             :     // Safe impossible cases
    1016             :     // It's an programming error if dispose is called before terminate!
    1017             : 
    1018             :     // But if you just ignore the assertion (which happens in unit
    1019             :     // tests for instance in sc/qa/unit) nothing bad happens.
    1020             :     SAL_WARN_IF( !m_bIsTerminated, "fwk", "Desktop disposed before terminating it" );
    1021             : 
    1022         305 :     SolarMutexClearableGuard aWriteLock;
    1023             : 
    1024             :     // Look for multiple calls of this method!
    1025             :     // If somewhere call dispose() twice - he will be stopped here really!!!
    1026         610 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1027             : 
    1028             :     // Now - we are alone and its the first call of this method ...
    1029             :     // otherwise call before had thrown a DisposedException / hopefully .-)
    1030             :     // But we dont use the transaction object created before ... we reset it immediately ...
    1031             :     // two lines of code ... for what ?
    1032             :     // The answer: We wished to synchronize concurrent dispose() calls -> OK
    1033             :     // But next line will wait for all currently running transaction (even if they
    1034             :     // are running within the same thread!) So we would block ourself there if aTransaction
    1035             :     // will stay registered .-)
    1036         305 :     aTransaction.stop();
    1037             : 
    1038             :     // Disable this instance for further work.
    1039             :     // This will wait for all current running transactions ...
    1040             :     // and reject all new incoming requests!
    1041         305 :     m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
    1042             : 
    1043         305 :     aWriteLock.clear();
    1044             : 
    1045             :     // Following lines of code can be called outside a synchronized block ...
    1046             :     // Because our transaction manager will block all new requests to this object.
    1047             :     // So nobody can use us any longer.
    1048             :     // Exception: Only removing of listener will work ... and this code can't be dangerous.
    1049             : 
    1050             :     // First we has to kill all listener connections.
    1051             :     // They might rely on our member and can hinder us on releasing them.
    1052         610 :     css::uno::Reference< css::uno::XInterface > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
    1053         610 :     css::lang::EventObject                      aEvent( xThis );
    1054         305 :     m_aListenerContainer.disposeAndClear( aEvent );
    1055             : 
    1056             :     // Clear our child task container and forget all task references hardly.
    1057             :     // Normally all open document was already closed by our terminate() function before ...
    1058             :     // New opened frames will have a problem now .-)
    1059         305 :     m_aChildTaskContainer.clear();
    1060             : 
    1061             :     // Dispose our helper too.
    1062         610 :     css::uno::Reference< css::lang::XEventListener > xFramesHelper( m_xFramesHelper, css::uno::UNO_QUERY );
    1063         305 :     if( xFramesHelper.is() )
    1064           0 :         xFramesHelper->disposing( aEvent );
    1065             : 
    1066             :     // At least clean up other member references.
    1067         305 :     m_xDispatchHelper.clear();
    1068         305 :     m_xFramesHelper.clear();
    1069         305 :     m_xLastFrame.clear();
    1070         305 :     m_xContext.clear();
    1071             : 
    1072         305 :     m_xPipeTerminator.clear();
    1073         305 :     m_xQuickLauncher.clear();
    1074         305 :     m_xSWThreadManager.clear();
    1075         305 :     m_xSfxTerminator.clear();
    1076             : 
    1077             :     // From this point nothing will work further on this object ...
    1078             :     // excepting our dtor() .-)
    1079         610 :     m_aTransactionManager.setWorkingMode( E_CLOSE );
    1080         305 : }
    1081             : 
    1082             : /*
    1083             :     @interface  XComponent
    1084             :     @short      add/remove listener for dispose events
    1085             :     @descr      Add an event listener to this object, if you wish to get information
    1086             :                 about our dieing!
    1087             :                 You must releas ethis listener reference during your own disposing() method.
    1088             : 
    1089             :     @attention  Our container is threadsafe himeslf. So we don't need any lock here.
    1090             :     @param      "xListener", reference to valid listener. We don't accept invalid values!
    1091             :     @threadsafe yes
    1092             : */
    1093         308 : void SAL_CALL Desktop::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
    1094             : {
    1095             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1096             :     // Safe impossible cases
    1097             :     // Method not defined for all incoming parameter.
    1098             :     SAL_WARN_IF( implcp_addEventListener( xListener ), "fwk", "Desktop::addEventListener(): Invalid parameter detected!" );
    1099             :     // Register transaction and reject wrong calls.
    1100         308 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1101             : 
    1102         308 :     m_aListenerContainer.addInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
    1103         308 : }
    1104             : 
    1105         132 : void SAL_CALL Desktop::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
    1106             : {
    1107             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1108             :     // Safe impossible cases
    1109             :     // Method not defined for all incoming parameter.
    1110             :     SAL_WARN_IF( implcp_removeEventListener( xListener ), "fwk", "Desktop::removeEventListener(): Invalid parameter detected!" );
    1111             :     // Register transaction and reject wrong calls.
    1112         132 :     TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
    1113             : 
    1114         132 :     m_aListenerContainer.removeInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
    1115         132 : }
    1116             : 
    1117             : /*-************************************************************************************************************
    1118             :     @interface  XDispatchResultListener
    1119             :     @short      callback for dispatches
    1120             :     @descr      To support our method "loadComponentFromURL()" we are listener on temp. created dispatcher.
    1121             :                 They call us back in this method "statusChanged()". As source of given state event, they give us a
    1122             :                 reference to the target frame, in which dispatch was loaded! So we can use it to return his component
    1123             :                 to caller! If no target exist ... ??!!
    1124             : 
    1125             :     @seealso    method loadComponentFromURL()
    1126             : 
    1127             :     @param      "aEvent", state event which (hopefully) valid information
    1128             :     @threadsafe yes
    1129             : *//*-*************************************************************************************************************/
    1130           0 : void SAL_CALL Desktop::dispatchFinished( const css::frame::DispatchResultEvent& aEvent ) throw( css::uno::RuntimeException, std::exception )
    1131             : {
    1132             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1133             :     // Register transaction and reject wrong calls.
    1134           0 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1135             : 
    1136           0 :     SolarMutexGuard g;
    1137           0 :     if( m_eLoadState != E_INTERACTION )
    1138             :     {
    1139           0 :         m_xLastFrame = css::uno::Reference< css::frame::XFrame >();
    1140           0 :         m_eLoadState = E_FAILED;
    1141           0 :         if( aEvent.State == css::frame::DispatchResultState::SUCCESS )
    1142             :         {
    1143           0 :             css::uno::Reference < css::frame::XFrame > xFrame;
    1144           0 :             if ( aEvent.Result >>= m_xLastFrame )
    1145           0 :                 m_eLoadState = E_SUCCESSFUL;
    1146             :         }
    1147           0 :     }
    1148           0 : }
    1149             : 
    1150             : /*-************************************************************************************************************
    1151             :     @interface  XEventListener
    1152             :     @short      not implemented!
    1153             :     @descr      We are a status listener ... and so we must be an event listener too ... But we don't need it really!
    1154             :                 We are a temp. listener only and our lifetime isn't smaller then of our temp. used dispatcher.
    1155             : 
    1156             :     @seealso    method loadComponentFromURL()
    1157             : *//*-*************************************************************************************************************/
    1158           0 : void SAL_CALL Desktop::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException, std::exception )
    1159             : {
    1160             :     SAL_WARN( "fwk", "Desktop::disposing(): Algorithm error! Normally desktop is temp. listener ... not all the time. So this method shouldn't be called." );
    1161           0 : }
    1162             : 
    1163             : /*-************************************************************************************************************
    1164             :     @interface  XInteractionHandler
    1165             :     @short      callback for loadComponentFromURL for detected exceptions during load process
    1166             :     @descr      In this case we must cancel loading and throw these detected exception again as result
    1167             :                 of our own called method.
    1168             : 
    1169             :     @attention  a)
    1170             :                 Normal loop in loadComponentFromURL() breaks on setted member m_eLoadState during callback statusChanged().
    1171             :                 But these interaction feature implements second way to do so! So we must look on different callbacks
    1172             :                 for same operation ... and live with it.
    1173             :                 b)
    1174             :                 Search for given continuations too. If any XInteractionAbort exist ... use it to abort further operations
    1175             :                 for currently running operation!
    1176             : 
    1177             :     @seealso    method loadComponentFromURL()
    1178             :     @seealso    member m_eLoadState
    1179             : 
    1180             :     @param      "xRequest", request for interaction - normal a wrapped target exception from bottom services
    1181             :     @threadsafe yes
    1182             : *//*-*************************************************************************************************************/
    1183           0 : void SAL_CALL Desktop::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest ) throw( css::uno::RuntimeException, std::exception )
    1184             : {
    1185             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1186             :     // Register transaction and reject wrong calls.
    1187           0 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1188             : 
    1189             :     // Don't check incoming request!
    1190             :     // If somewhere starts interaction without right parameter - he maked something wrong.
    1191             :     // loadComponentFromURL() waits for thjese event - otherwise it yield for ever!
    1192             : 
    1193             :     // get packed request and work on it first
    1194             :     // Attention: Don't set it on internal member BEFORE interaction is finished - because
    1195             :     // "loadComponentFromURL()" yield tills this member is changed. If we do it before
    1196             :     // interaction finish we can't guarantee right functionality. May be we cancel load process to erliear ...
    1197           0 :     css::uno::Any aRequest = xRequest->getRequest();
    1198             : 
    1199             :     // extract continuations from request
    1200           0 :     css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
    1201           0 :     css::uno::Reference< css::task::XInteractionAbort >                              xAbort;
    1202           0 :     css::uno::Reference< css::task::XInteractionApprove >                            xApprove;
    1203           0 :     css::uno::Reference< css::document::XInteractionFilterSelect >                   xFilterSelect;
    1204           0 :     bool                                                                             bAbort         = false;
    1205             : 
    1206           0 :     sal_Int32 nCount=lContinuations.getLength();
    1207           0 :     for( sal_Int32 nStep=0; nStep<nCount; ++nStep )
    1208             :     {
    1209           0 :         if( ! xAbort.is() )
    1210           0 :             xAbort  = css::uno::Reference< css::task::XInteractionAbort >( lContinuations[nStep], css::uno::UNO_QUERY );
    1211             : 
    1212           0 :         if( ! xApprove.is() )
    1213           0 :             xApprove  = css::uno::Reference< css::task::XInteractionApprove >( lContinuations[nStep], css::uno::UNO_QUERY );
    1214             : 
    1215           0 :         if( ! xFilterSelect.is() )
    1216           0 :             xFilterSelect = css::uno::Reference< css::document::XInteractionFilterSelect >( lContinuations[nStep], css::uno::UNO_QUERY );
    1217             :     }
    1218             : 
    1219             :     // differ between abortable interactions (error, unknown filter ...)
    1220             :     // and other ones (ambigous but not unknown filter ...)
    1221           0 :     css::task::ErrorCodeRequest          aErrorCodeRequest;
    1222           0 :     if( aRequest >>= aErrorCodeRequest )
    1223             :     {
    1224           0 :         bool bWarning = ((aErrorCodeRequest.ErrCode & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
    1225           0 :         if (xApprove.is() && bWarning)
    1226           0 :             xApprove->select();
    1227             :         else
    1228           0 :         if (xAbort.is())
    1229             :         {
    1230           0 :             xAbort->select();
    1231           0 :             bAbort = true;
    1232             :         }
    1233             :     }
    1234           0 :     else if( xAbort.is() )
    1235             :     {
    1236           0 :         xAbort->select();
    1237           0 :         bAbort = true;
    1238             :     }
    1239             : 
    1240             :     // Ok now it's time to break yield loop of loadComponentFromURL().
    1241             :     // But only for really aborted requests!
    1242             :     // For example warnings will be approved and we wait for any success story ...
    1243           0 :     if (bAbort)
    1244             :     {
    1245           0 :         SolarMutexGuard g;
    1246           0 :         m_eLoadState          = E_INTERACTION;
    1247           0 :         m_aInteractionRequest = aRequest;
    1248           0 :     }
    1249           0 : }
    1250             : 
    1251        2098 : ::sal_Int32 SAL_CALL Desktop::leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent )
    1252             :     throw (css::lang::IllegalArgumentException,
    1253             :            css::uno::RuntimeException, std::exception         )
    1254             : {
    1255        2098 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1256        2098 :     return m_xTitleNumberGenerator->leaseNumber (xComponent);
    1257             : }
    1258             : 
    1259        2095 : void SAL_CALL Desktop::releaseNumber( ::sal_Int32 nNumber )
    1260             :     throw (css::lang::IllegalArgumentException,
    1261             :            css::uno::RuntimeException, std::exception         )
    1262             : {
    1263        2095 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1264        2095 :     m_xTitleNumberGenerator->releaseNumber (nNumber);
    1265        2095 : }
    1266             : 
    1267           0 : void SAL_CALL Desktop::releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent )
    1268             :     throw (css::lang::IllegalArgumentException,
    1269             :            css::uno::RuntimeException, std::exception         )
    1270             : {
    1271           0 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1272           0 :     m_xTitleNumberGenerator->releaseNumberForComponent (xComponent);
    1273           0 : }
    1274             : 
    1275       11060 : OUString SAL_CALL Desktop::getUntitledPrefix()
    1276             :     throw (css::uno::RuntimeException, std::exception)
    1277             : {
    1278       11060 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1279       11060 :     return m_xTitleNumberGenerator->getUntitledPrefix ();
    1280             : }
    1281             : 
    1282             : /*-************************************************************************************************************
    1283             :     @short      try to convert a property value
    1284             :     @descr      This method is called from helperclass "OPropertySetHelper".
    1285             :                 Don't use this directly!
    1286             :                 You must try to convert the value of given DESKTOP_PROPHANDLE and
    1287             :                 return results of this operation. This will be used to ask vetoable
    1288             :                 listener. If no listener has a veto, we will change value really!
    1289             :                 ( in method setFastPropertyValue_NoBroadcast(...) )
    1290             : 
    1291             :     @attention  Methods of OPropertySethelper are safed by using our shared osl mutex! (see ctor!)
    1292             :                 So we must use different locks to make our implementation threadsafe.
    1293             : 
    1294             :     @seealso    class OPropertySetHelper
    1295             :     @seealso    method setFastPropertyValue_NoBroadcast()
    1296             : 
    1297             :     @param      "aConvertedValue"   new converted value of property
    1298             :     @param      "aOldValue"         old value of property
    1299             :     @param      "nHandle"           handle of property
    1300             :     @param      "aValue"            new value of property
    1301             :     @return     sal_True if value will be changed, sal_FALSE otherway
    1302             : 
    1303             :     @onerror    IllegalArgumentException, if you call this with an invalid argument
    1304             :     @threadsafe yes
    1305             : *//*-*************************************************************************************************************/
    1306           2 : sal_Bool SAL_CALL Desktop::convertFastPropertyValue(       css::uno::Any&   aConvertedValue ,
    1307             :                                                            css::uno::Any&   aOldValue       ,
    1308             :                                                            sal_Int32        nHandle         ,
    1309             :                                                      const css::uno::Any&   aValue          ) throw( css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception )
    1310             : {
    1311             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1312             :     // Register transaction and reject wrong calls.
    1313           2 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1314             : 
    1315             :     //  Initialize state with sal_False !!!
    1316             :     //  (Handle can be invalid)
    1317           2 :     bool bReturn = false;
    1318             : 
    1319           2 :     switch( nHandle )
    1320             :     {
    1321             :         case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO:
    1322             :                 bReturn = PropHelper::willPropertyBeChanged(
    1323             :                     css::uno::makeAny(m_bSuspendQuickstartVeto),
    1324             :                     aValue,
    1325             :                     aOldValue,
    1326           0 :                     aConvertedValue);
    1327           0 :                 break;
    1328             :         case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
    1329             :                 bReturn = PropHelper::willPropertyBeChanged(
    1330             :                     css::uno::makeAny(m_xDispatchRecorderSupplier),
    1331             :                     aValue,
    1332             :                     aOldValue,
    1333           0 :                     aConvertedValue);
    1334           0 :                 break;
    1335             :         case DESKTOP_PROPHANDLE_TITLE :
    1336             :                 bReturn = PropHelper::willPropertyBeChanged(
    1337             :                     css::uno::makeAny(m_sTitle),
    1338             :                     aValue,
    1339             :                     aOldValue,
    1340           2 :                     aConvertedValue);
    1341           2 :                 break;
    1342             :     }
    1343             : 
    1344             :     // Return state of operation.
    1345           2 :     return bReturn;
    1346             : }
    1347             : 
    1348             : /*-************************************************************************************************************
    1349             :     @short      set value of a transient property
    1350             :     @descr      This method is calling from helperclass "OPropertySetHelper".
    1351             :                 Don't use this directly!
    1352             :                 Handle and value are valid everyway! You must set the new value only.
    1353             :                 After this, baseclass send messages to all listener automatically.
    1354             : 
    1355             :     @seealso    class OPropertySetHelper
    1356             : 
    1357             :     @param      "nHandle"   handle of property to change
    1358             :     @param      "aValue"    new value of property
    1359             :     @onerror    An exception is thrown.
    1360             :     @threadsafe yes
    1361             : *//*-*************************************************************************************************************/
    1362           2 : void SAL_CALL Desktop::setFastPropertyValue_NoBroadcast(       sal_Int32        nHandle ,
    1363             :                                                          const css::uno::Any&   aValue  ) throw( css::uno::Exception, std::exception )
    1364             : {
    1365             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1366             :     // Register transaction and reject wrong calls.
    1367           2 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1368             : 
    1369           2 :     switch( nHandle )
    1370             :     {
    1371           0 :         case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO:    aValue >>= m_bSuspendQuickstartVeto;
    1372           0 :                                                     break;
    1373           0 :         case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER:    aValue >>= m_xDispatchRecorderSupplier;
    1374           0 :                                                     break;
    1375           2 :         case DESKTOP_PROPHANDLE_TITLE:    aValue >>= m_sTitle;
    1376           2 :                                                     break;
    1377           2 :     }
    1378           2 : }
    1379             : 
    1380             : /*-************************************************************************************************************
    1381             :     @short      get value of a transient property
    1382             :     @descr      This method is calling from helperclass "OPropertySetHelper".
    1383             :                 Don't use this directly!
    1384             : 
    1385             :     @attention  We don't need any mutex or lock here ... We use threadsafe container or methods here only!
    1386             : 
    1387             :     @seealso    class OPropertySetHelper
    1388             : 
    1389             :     @param      "nHandle"   handle of property to change
    1390             :     @param      "aValue"    current value of property
    1391             :     @threadsafe yes
    1392             : *//*-*************************************************************************************************************/
    1393           4 : void SAL_CALL Desktop::getFastPropertyValue( css::uno::Any& aValue  ,
    1394             :                                              sal_Int32      nHandle ) const
    1395             : {
    1396             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1397             :     // Register transaction and reject wrong calls.
    1398           4 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1399             : 
    1400           4 :     switch( nHandle )
    1401             :     {
    1402           0 :         case DESKTOP_PROPHANDLE_ACTIVEFRAME           :   aValue <<= m_aChildTaskContainer.getActive();
    1403           0 :                                                     break;
    1404           0 :         case DESKTOP_PROPHANDLE_ISPLUGGED           :   aValue <<= sal_False;
    1405           0 :                                                     break;
    1406           0 :         case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO:    aValue <<= m_bSuspendQuickstartVeto;
    1407           0 :                                                     break;
    1408           0 :         case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER:    aValue <<= m_xDispatchRecorderSupplier;
    1409           0 :                                                     break;
    1410           4 :         case DESKTOP_PROPHANDLE_TITLE:    aValue <<= m_sTitle;
    1411           4 :                                                     break;
    1412           4 :     }
    1413           4 : }
    1414             : 
    1415             : /*-************************************************************************************************************
    1416             :     @short      return structure and information about transient properties
    1417             :     @descr      This method is calling from helperclass "OPropertySetHelper".
    1418             :                 Don't use this directly!
    1419             : 
    1420             :     @attention  You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
    1421             :                 Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
    1422             :                 So we could have two different mutex/lock mechanism at the same object.
    1423             : 
    1424             :     @seealso    class OPropertySetHelper
    1425             :     @return     structure with property-information
    1426             :     @threadsafe yes
    1427             : *//*-*************************************************************************************************************/
    1428          22 : ::cppu::IPropertyArrayHelper& SAL_CALL Desktop::getInfoHelper()
    1429             : {
    1430             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1431             :     // Register transaction and reject wrong calls.
    1432          22 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1433             : 
    1434             :     // Optimize this method !
    1435             :     // We initialize a static variable only one time. And we don't must use a mutex at every call!
    1436             :     // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
    1437             :     static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
    1438             : 
    1439          22 :     if( pInfoHelper == NULL )
    1440             :     {
    1441           8 :         SolarMutexGuard aGuard;
    1442             : 
    1443             :         // Control this pointer again, another instance can be faster then these!
    1444           8 :         if( pInfoHelper == NULL )
    1445             :         {
    1446             :             // Define static member to give structure of properties to baseclass "OPropertySetHelper".
    1447             :             // "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable.
    1448             :             // "sal_True" say: Table is sorted by name.
    1449           8 :             static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
    1450           8 :             pInfoHelper = &aInfoHelper;
    1451           8 :         }
    1452             :     }
    1453             : 
    1454          22 :     return(*pInfoHelper);
    1455             : }
    1456             : 
    1457             : /*-************************************************************************************************************
    1458             :     @short      return propertysetinfo
    1459             :     @descr      You can call this method to get information about transient properties
    1460             :                 of this object.
    1461             : 
    1462             :     @attention  You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
    1463             :                 Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
    1464             :                 So we could have two different mutex/lock mechanism at the same object.
    1465             : 
    1466             :     @seealso    class OPropertySetHelper
    1467             :     @seealso    interface XPropertySet
    1468             :     @seealso    interface XMultiPropertySet
    1469             :     @return     reference to object with information [XPropertySetInfo]
    1470             :     @threadsafe yes
    1471             : *//*-*************************************************************************************************************/
    1472          26 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL Desktop::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException, std::exception)
    1473             : {
    1474             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1475             :     // Register transaction and reject wrong calls.
    1476          26 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1477             : 
    1478             :     // Optimize this method !
    1479             :     // We initialize a static variable only one time. And we don't must use a mutex at every call!
    1480             :     // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
    1481             :     static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL;
    1482             : 
    1483          26 :     if( pInfo == NULL )
    1484             :     {
    1485           8 :         SolarMutexGuard aGuard;
    1486             : 
    1487             :         // Control this pointer again, another instance can be faster then these!
    1488           8 :         if( pInfo == NULL )
    1489             :         {
    1490             :             // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
    1491             :             // (Use method "getInfoHelper()".)
    1492             :             static css::uno::Reference< css::beans::XPropertySetInfo > xInfo(
    1493           8 :                     cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() ) );
    1494           8 :             pInfo = &xInfo;
    1495           8 :         }
    1496             :     }
    1497             : 
    1498          26 :     return (*pInfo);
    1499             : }
    1500             : 
    1501             : /*-************************************************************************************************************
    1502             :     @short      return current component of current frame
    1503             :     @descr      The desktop himself has no component. But every frame in subtree.
    1504             :                 If somewhere call getCurrentComponent() at this class, we try to find the right frame and
    1505             :                 then we try to become his component. It can be a VCL-component, the model or the controller
    1506             :                 of founded frame.
    1507             : 
    1508             :     @attention  We don't work on internal member ... so we don't need any lock here.
    1509             : 
    1510             :     @seealso    method getCurrentComponent();
    1511             : 
    1512             :     @param      "xFrame", reference to valid frame in hierarchy. Method is not defined for invalid values.
    1513             :                 But we don't check these. Its an IMPL-method and caller must use it right!
    1514             :     @return     A reference to found component.
    1515             : 
    1516             :     @onerror    A null reference is returned.
    1517             :     @threadsafe yes
    1518             : *//*-*************************************************************************************************************/
    1519           0 : css::uno::Reference< css::lang::XComponent > Desktop::impl_getFrameComponent( const css::uno::Reference< css::frame::XFrame >& xFrame ) const
    1520             : {
    1521             :     /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
    1522             :     // Register transaction and reject wrong calls.
    1523           0 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1524             : 
    1525             :     // Set default return value, if method failed.
    1526           0 :     css::uno::Reference< css::lang::XComponent > xComponent;
    1527             :     // Does no controller exists?
    1528           0 :     css::uno::Reference< css::frame::XController > xController = xFrame->getController();
    1529           0 :     if( !xController.is() )
    1530             :     {
    1531             :         // Controller not exist - use the VCL-component.
    1532           0 :         xComponent = css::uno::Reference< css::lang::XComponent >( xFrame->getComponentWindow(), css::uno::UNO_QUERY );
    1533             :     }
    1534             :     else
    1535             :     {
    1536             :         // Does no model exists?
    1537           0 :         css::uno::Reference< css::frame::XModel > xModel( xController->getModel(), css::uno::UNO_QUERY );
    1538           0 :         if( xModel.is() )
    1539             :         {
    1540             :             // Model exist - use the model as component.
    1541           0 :             xComponent = css::uno::Reference< css::lang::XComponent >( xModel, css::uno::UNO_QUERY );
    1542             :         }
    1543             :         else
    1544             :         {
    1545             :             // Model not exist - use the controller as component.
    1546           0 :             xComponent = css::uno::Reference< css::lang::XComponent >( xController, css::uno::UNO_QUERY );
    1547           0 :         }
    1548             :     }
    1549             : 
    1550           0 :     return xComponent;
    1551             : }
    1552             : 
    1553             : /*-************************************************************************************************************
    1554             :     @short      create table with information about properties
    1555             :     @descr      We use a helper class to support properties. These class need some information about this.
    1556             :                 These method create a new static description table with name, type, r/w-flags and so on ...
    1557             : 
    1558             :     @seealso    class OPropertySetHelper
    1559             :     @seealso    method getInfoHelper()
    1560             :     @return     Static table with information about properties.
    1561             :     @threadsafe yes
    1562             : *//*-*************************************************************************************************************/
    1563           8 : const css::uno::Sequence< css::beans::Property > Desktop::impl_getStaticPropertyDescriptor()
    1564             : {
    1565             :     // Create a property array to initialize sequence!
    1566             :     // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
    1567             :     // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
    1568             :     // It's necessary for methods of OPropertySetHelper.
    1569             :     // ATTENTION:
    1570             :     //      YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
    1571             : 
    1572             :     const css::beans::Property pProperties[] =
    1573             :     {
    1574           8 :         css::beans::Property( DESKTOP_PROPNAME_ACTIVEFRAME              , DESKTOP_PROPHANDLE_ACTIVEFRAME             , cppu::UnoType<css::lang::XComponent>::get(), css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
    1575           8 :         css::beans::Property( DESKTOP_PROPNAME_DISPATCHRECORDERSUPPLIER , DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER, cppu::UnoType<css::frame::XDispatchRecorderSupplier>::get(), css::beans::PropertyAttribute::TRANSIENT ),
    1576           8 :         css::beans::Property( DESKTOP_PROPNAME_ISPLUGGED                , DESKTOP_PROPHANDLE_ISPLUGGED               , ::getBooleanCppuType()                                                                  , css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
    1577           8 :         css::beans::Property( DESKTOP_PROPNAME_SUSPENDQUICKSTARTVETO    , DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO   , ::getBooleanCppuType()                                                                  , css::beans::PropertyAttribute::TRANSIENT ),
    1578           8 :         css::beans::Property( DESKTOP_PROPNAME_TITLE                    , DESKTOP_PROPHANDLE_TITLE                   , cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::TRANSIENT ),
    1579          88 :     };
    1580             :     // Use it to initialize sequence!
    1581           8 :     const css::uno::Sequence< css::beans::Property > lPropertyDescriptor( pProperties, DESKTOP_PROPCOUNT );
    1582             :     // Return "PropertyDescriptor"
    1583          48 :     return lPropertyDescriptor;
    1584             : }
    1585             : 
    1586         168 : void Desktop::impl_sendQueryTerminationEvent(Desktop::TTerminateListenerList& lCalledListener,
    1587             :                                              bool&                      bVeto          )
    1588             : {
    1589         168 :     bVeto = false;
    1590             : 
    1591         168 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1592             : 
    1593         168 :     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::frame::XTerminateListener>::get());
    1594         168 :     if ( ! pContainer )
    1595         114 :         return;
    1596             : 
    1597         108 :     css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
    1598             : 
    1599         108 :     ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
    1600         222 :     while ( aIterator.hasMoreElements() )
    1601             :     {
    1602             :         try
    1603             :         {
    1604         114 :             css::uno::Reference< css::frame::XTerminateListener > xListener(aIterator.next(), css::uno::UNO_QUERY);
    1605         114 :             if ( ! xListener.is() )
    1606           0 :                 continue;
    1607         114 :             xListener->queryTermination( aEvent );
    1608         114 :             lCalledListener.push_back(xListener);
    1609             :         }
    1610           0 :         catch( const css::frame::TerminationVetoException& )
    1611             :         {
    1612             :             // first veto will stop notification loop.
    1613           0 :             bVeto = true;
    1614           0 :             return;
    1615             :         }
    1616           4 :         catch( const css::uno::Exception& )
    1617             :         {
    1618             :             // clean up container.
    1619             :             // E.g. dead remote listener objects can make trouble otherwise.
    1620             :             // Iterator implementation allows removing objects during it's used !
    1621           2 :             aIterator.remove();
    1622             :         }
    1623          54 :     }
    1624             : }
    1625             : 
    1626           0 : void Desktop::impl_sendCancelTerminationEvent(const Desktop::TTerminateListenerList& lCalledListener)
    1627             : {
    1628           0 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1629             : 
    1630           0 :     css::lang::EventObject                          aEvent( static_cast< ::cppu::OWeakObject* >(this) );
    1631           0 :     Desktop::TTerminateListenerList::const_iterator pIt;
    1632           0 :     for (  pIt  = lCalledListener.begin();
    1633           0 :            pIt != lCalledListener.end  ();
    1634             :          ++pIt                           )
    1635             :     {
    1636             :         try
    1637             :         {
    1638             :             // Note: cancelTermination() is a new and optional interface method !
    1639           0 :             css::uno::Reference< css::frame::XTerminateListener  > xListener           = *pIt;
    1640           0 :             css::uno::Reference< css::frame::XTerminateListener2 > xListenerGeneration2(xListener, css::uno::UNO_QUERY);
    1641           0 :             if ( ! xListenerGeneration2.is() )
    1642           0 :                 continue;
    1643           0 :             xListenerGeneration2->cancelTermination( aEvent );
    1644             :         }
    1645           0 :         catch( const css::uno::Exception& )
    1646             :         {}
    1647           0 :     }
    1648           0 : }
    1649             : 
    1650         168 : void Desktop::impl_sendNotifyTerminationEvent()
    1651             : {
    1652         168 :     TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
    1653             : 
    1654         168 :     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::frame::XTerminateListener>::get());
    1655         168 :     if ( ! pContainer )
    1656         282 :         return;
    1657             : 
    1658         108 :     css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
    1659             : 
    1660         108 :     ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
    1661         220 :     while ( aIterator.hasMoreElements() )
    1662             :     {
    1663             :         try
    1664             :         {
    1665         112 :             css::uno::Reference< css::frame::XTerminateListener > xListener(aIterator.next(), css::uno::UNO_QUERY);
    1666         112 :             if ( ! xListener.is() )
    1667           0 :                 continue;
    1668         112 :             xListener->notifyTermination( aEvent );
    1669             :         }
    1670           0 :         catch( const css::uno::Exception& )
    1671             :         {
    1672             :             // clean up container.
    1673             :             // E.g. dead remote listener objects can make trouble otherwise.
    1674             :             // Iterator implementation allows removing objects during it's used !
    1675           0 :             aIterator.remove();
    1676             :         }
    1677          54 :     }
    1678             : }
    1679             : 
    1680         168 : bool Desktop::impl_closeFrames(bool bAllowUI)
    1681             : {
    1682         168 :     SolarMutexClearableGuard aReadLock;
    1683         336 :     css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > lFrames = m_aChildTaskContainer.getAllElements();
    1684         168 :     aReadLock.clear();
    1685             : 
    1686         168 :     ::sal_Int32 c                = lFrames.getLength();
    1687         168 :     ::sal_Int32 i                = 0;
    1688         168 :     ::sal_Int32 nNonClosedFrames = 0;
    1689             : 
    1690         175 :     for( i=0; i<c; ++i )
    1691             :     {
    1692             :         try
    1693             :         {
    1694           7 :             css::uno::Reference< css::frame::XFrame > xFrame = lFrames[i];
    1695             : 
    1696             :             // XController.suspend() will show an UI ...
    1697             :             // Use it in case it was allowed from outside only.
    1698           7 :             bool                                       bSuspended = false;
    1699           7 :             css::uno::Reference< css::frame::XController > xController( xFrame->getController(), css::uno::UNO_QUERY );
    1700           7 :             if (
    1701          14 :                 ( bAllowUI         ) &&
    1702           7 :                 ( xController.is() )
    1703             :                )
    1704             :             {
    1705           7 :                 bSuspended = xController->suspend( sal_True );
    1706           7 :                 if ( ! bSuspended )
    1707             :                 {
    1708           0 :                     ++nNonClosedFrames;
    1709           0 :                     continue;
    1710             :                 }
    1711             :             }
    1712             : 
    1713             :             // Try to close frame (in case no UI was allowed without calling XController->suspend() before!)
    1714             :             // But don't deliver ownership to any other one!
    1715             :             // This method can be called again.
    1716           7 :             css::uno::Reference< css::util::XCloseable > xClose( xFrame, css::uno::UNO_QUERY );
    1717           7 :             if ( xClose.is() )
    1718             :             {
    1719             :                 try
    1720             :                 {
    1721           7 :                     xClose->close(sal_False);
    1722             :                 }
    1723           0 :                 catch(const css::util::CloseVetoException&)
    1724             :                 {
    1725             :                     // Any internal process of this frame disagree with our request.
    1726             :                     // Safe this state but dont break these loop. Other frames has to be closed!
    1727           0 :                     ++nNonClosedFrames;
    1728             : 
    1729             :                     // Reactivate controller.
    1730             :                     // It can happen that XController.suspend() returned true ... but a registered close listener
    1731             :                     // throwed these veto exception. Then the controller has to be reactivated. Otherwise
    1732             :                     // these document doesn't work any more.
    1733           0 :                     if (
    1734           0 :                         (bSuspended      ) &&
    1735           0 :                         (xController.is())
    1736             :                        )
    1737           0 :                         xController->suspend(sal_False);
    1738             :                 }
    1739             : 
    1740             :                 // If interface XClosable interface exists and was used ...
    1741             :                 // it's not allowed to use XComponent->dispose() also !
    1742           7 :                 continue;
    1743             :             }
    1744             : 
    1745             :             // XClosable not supported ?
    1746             :             // Then we have to dispose these frame hardly.
    1747           0 :             css::uno::Reference< css::lang::XComponent > xDispose( xFrame, css::uno::UNO_QUERY );
    1748           0 :             if ( xDispose.is() )
    1749           0 :                 xDispose->dispose();
    1750             : 
    1751             :             // Don't remove these frame from our child container!
    1752             :             // A frame do it by itself inside close()/dispose() method.
    1753             :         }
    1754           0 :         catch(const css::lang::DisposedException&)
    1755             :         {
    1756             :             // Dispose frames are closed frames.
    1757             :             // So we can count it here .-)
    1758             :         }
    1759             :     }
    1760             : 
    1761         336 :     return (nNonClosedFrames < 1);
    1762             : }
    1763             : 
    1764             : //  We work with valid listener only.
    1765           0 : bool Desktop::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
    1766             : {
    1767           0 :     return !xListener.is();
    1768             : }
    1769             : 
    1770             : //  We work with valid listener only.
    1771           0 : bool Desktop::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
    1772             : {
    1773           0 :     return !xListener.is();
    1774             : }
    1775             : 
    1776             : }   // namespace framework
    1777             : 
    1778             : namespace {
    1779             : 
    1780         309 : struct Instance {
    1781         309 :     explicit Instance(
    1782             :         css::uno::Reference<css::uno::XComponentContext> const & context):
    1783         309 :         instance(static_cast<cppu::OWeakObject *>(new framework::Desktop(context)))
    1784             :     {
    1785             :         static_cast<framework::Desktop *>(static_cast<cppu::OWeakObject *>
    1786         309 :                 (instance.get()))->constructorInit();
    1787         309 :     }
    1788             : 
    1789             :     css::uno::Reference<css::uno::XInterface> instance;
    1790             : };
    1791             : 
    1792             : struct Singleton:
    1793             :     public rtl::StaticWithArg<
    1794             :         Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
    1795             : {};
    1796             : 
    1797             : }
    1798             : 
    1799             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1800       34152 : com_sun_star_comp_framework_Desktop_get_implementation(
    1801             :     css::uno::XComponentContext *context,
    1802             :     css::uno::Sequence<css::uno::Any> const &)
    1803             : {
    1804             :     return cppu::acquire(static_cast<cppu::OWeakObject *>(
    1805       34152 :                 Singleton::get(context).instance.get()));
    1806         951 : }
    1807             : 
    1808             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10