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