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

Generated by: LCOV version 1.11