1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <loadenv/loadenv.hxx>
22 #include <loadenv/targethelper.hxx>
24 #include <services/desktop.hxx>
25 #include <helper/ocomponentaccess.hxx>
26 #include <dispatch/dispatchprovider.hxx>
28 #include <dispatch/interceptionhelper.hxx>
29 #include <classes/taskcreator.hxx>
30 #include <threadhelp/transactionguard.hxx>
31 #include <threadhelp/writeguard.hxx>
32 #include <threadhelp/readguard.hxx>
35 #include <properties.h>
37 #include <classes/resource.hrc>
38 #include <classes/fwkresid.hxx>
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <com/sun/star/frame/FrameSearchFlag.hpp>
42 #include <com/sun/star/awt/XWindow.hpp>
43 #include <com/sun/star/awt/XWindowPeer.hpp>
44 #include <com/sun/star/awt/WindowDescriptor.hpp>
45 #include <com/sun/star/awt/WindowAttribute.hpp>
46 #include <com/sun/star/awt/PosSize.hpp>
47 #include <com/sun/star/util/XURLTransformer.hpp>
48 #include <com/sun/star/task/XInteractionAbort.hpp>
49 #include <com/sun/star/task/XInteractionApprove.hpp>
50 #include <com/sun/star/document/XInteractionFilterSelect.hpp>
51 #include <com/sun/star/document/AmbigousFilterRequest.hpp>
52 #include <com/sun/star/task/ErrorCodeRequest.hpp>
53 #include <com/sun/star/ucb/InteractiveIOException.hpp>
54 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
55 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
56 #include <com/sun/star/frame/DispatchResultState.hpp>
57 #include <com/sun/star/lang/IllegalArgumentException.hpp>
58 #include <com/sun/star/lang/DisposedException.hpp>
59 #include <com/sun/star/util/XCloseable.hpp>
60 #include <com/sun/star/document/MacroExecMode.hpp>
61 #include <com/sun/star/document/UpdateDocMode.hpp>
62 #include <com/sun/star/frame/XTerminateListener2.hpp>
64 #include <cppuhelper/queryinterface.hxx>
65 #include <cppuhelper/typeprovider.hxx>
66 #include <cppuhelper/factory.hxx>
67 #include <cppuhelper/proptypehlp.hxx>
68 #include <rtl/ustrbuf.hxx>
69 #include <rtl/logfile.hxx>
70 #include <vcl/svapp.hxx>
72 #include <tools/errinf.hxx>
73 #include <comphelper/extract.hxx>
75 #include <fwkdllapi.h>
79 //*****************************************************************************************************************
80 // XInterface, XTypeProvider, XServiceInfo
81 //*****************************************************************************************************************
82 DEFINE_XINTERFACE_16 ( Desktop
,
84 DIRECT_INTERFACE( css::lang::XTypeProvider
),
85 DIRECT_INTERFACE( css::lang::XServiceInfo
),
86 DIRECT_INTERFACE( css::frame::XDesktop2
),
87 DIRECT_INTERFACE( css::frame::XDesktop
),
88 DIRECT_INTERFACE( css::frame::XComponentLoader
),
89 DIRECT_INTERFACE( css::frame::XTasksSupplier
),
90 DIRECT_INTERFACE( css::frame::XDispatchProvider
),
91 DIRECT_INTERFACE( css::frame::XDispatchProviderInterception
),
92 DIRECT_INTERFACE( css::frame::XFramesSupplier
),
93 DIRECT_INTERFACE( css::frame::XFrame
),
94 DIRECT_INTERFACE( css::lang::XComponent
),
95 DIRECT_INTERFACE( css::frame::XDispatchResultListener
),
96 DIRECT_INTERFACE( css::lang::XEventListener
),
97 DIRECT_INTERFACE( css::task::XInteractionHandler
),
98 DIRECT_INTERFACE( css::beans::XPropertySet
),
99 DIRECT_INTERFACE( css::frame::XUntitledNumbers
)
102 DEFINE_XTYPEPROVIDER_16 ( Desktop
,
103 css::lang::XTypeProvider
,
104 css::lang::XServiceInfo
,
105 css::frame::XDesktop2
,
106 css::frame::XDesktop
,
107 css::frame::XComponentLoader
,
108 css::frame::XTasksSupplier
,
109 css::frame::XDispatchProvider
,
110 css::frame::XDispatchProviderInterception
,
111 css::frame::XFramesSupplier
,
113 css::lang::XComponent
,
114 css::frame::XDispatchResultListener
,
115 css::lang::XEventListener
,
116 css::task::XInteractionHandler
,
117 css::beans::XPropertySet
,
118 css::frame::XUntitledNumbers
121 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( Desktop
,
122 ::cppu::OWeakObject
,
123 DECLARE_ASCII("com.sun.star.frame.Desktop" ),
124 IMPLEMENTATIONNAME_DESKTOP
127 DEFINE_INIT_SERVICE ( Desktop
,
130 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
131 to create a new instance of this class by our own supported service factory.
132 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further information!
135 //-------------------------------------------------------------------------------------------------------------
136 // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
137 // We hold member as reference ... not as pointer too!
138 // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
139 // But look on dispose() for right order of deinitialization.
140 OFrames
* pFramesHelper
= new OFrames( m_xFactory
, this, &m_aChildTaskContainer
);
141 m_xFramesHelper
= css::uno::Reference
< css::frame::XFrames
>( static_cast< ::cppu::OWeakObject
* >(pFramesHelper
), css::uno::UNO_QUERY
);
143 //-------------------------------------------------------------------------------------------------------------
144 // Initialize a new dispatchhelper-object to handle dispatches.
145 // We use these helper as slave for our interceptor helper ... not directly!
146 // But he is event listener on THIS instance!
147 DispatchProvider
* pDispatchHelper
= new DispatchProvider( m_xFactory
, this );
148 css::uno::Reference
< css::frame::XDispatchProvider
> xDispatchProvider( static_cast< ::cppu::OWeakObject
* >(pDispatchHelper
), css::uno::UNO_QUERY
);
150 //-------------------------------------------------------------------------------------------------------------
151 // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
152 // Set created dispatch provider as slowest slave of it.
153 // Hold interception helper by reference only - not by pointer!
154 // So it's easiear to destroy it.
155 InterceptionHelper
* pInterceptionHelper
= new InterceptionHelper( this, xDispatchProvider
);
156 m_xDispatchHelper
= css::uno::Reference
< css::frame::XDispatchProvider
>( static_cast< ::cppu::OWeakObject
* >(pInterceptionHelper
), css::uno::UNO_QUERY
);
158 OUStringBuffer
sUntitledPrefix (256);
159 sUntitledPrefix
.append (OUString( String( FwkResId( STR_UNTITLED_DOCUMENT
))));
160 sUntitledPrefix
.appendAscii (" ");
162 ::comphelper::NumberedCollection
* pNumbers
= new ::comphelper::NumberedCollection ();
163 m_xTitleNumberGenerator
= css::uno::Reference
< css::frame::XUntitledNumbers
>(static_cast< ::cppu::OWeakObject
* >(pNumbers
), css::uno::UNO_QUERY_THROW
);
164 pNumbers
->setOwner ( static_cast< ::cppu::OWeakObject
* >(this) );
165 pNumbers
->setUntitledPrefix ( sUntitledPrefix
.makeStringAndClear () );
167 // Safe impossible cases
168 // We can't work without this helper!
169 LOG_ASSERT2( m_xFramesHelper
.is ()==sal_False
, "Desktop::Desktop()", "Frames helper is not valid. XFrames, XIndexAccess and XElementAcces are not supported!\n")
170 LOG_ASSERT2( m_xDispatchHelper
.is()==sal_False
, "Desktop::Desktop()", "Dispatch helper is not valid. XDispatch will not work correctly!\n" )
172 // Enable object for real working!
173 // Otherwise all calls will be rejected ...
174 m_aTransactionManager
.setWorkingMode( E_WORK
);
178 /*-************************************************************************************************************//**
179 @short standard constructor to create instance by factory
180 @descr This constructor initialize a new instance of this class by valid factory,
181 and will be set valid values on his member and baseclasses.
183 @attention a) Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
184 will get over this. (e.g. using of your reference as parameter to initialize some member)
185 Do such things in DEFINE_INIT_SERVICE() method, which is called automaticly after your ctor!!!
186 b) Baseclass OBroadcastHelper is a typedef in namespace cppu!
187 The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
188 If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
189 I don't know why! (other compiler not tested .. but it works!)
191 @seealso method DEFINE_INIT_SERVICE()
193 @param "xFactory" is the multi service manager, which create this instance.
194 The value must be different from NULL!
197 @onerror We throw an ASSERT in debug version or do nothing in relaese version.
198 *//*-*************************************************************************************************************/
199 Desktop::Desktop( const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xFactory
)
200 // Init baseclasses first
201 // Attention: Don't change order of initialization!
202 // ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
203 // We must guarantee right initialization and a valid value of this to initialize other baseclasses!
204 : ThreadHelpBase ( &Application::GetSolarMutex() )
205 , TransactionBase ( )
206 , ::cppu::OBroadcastHelperVar
< ::cppu::OMultiTypeInterfaceContainerHelper
, ::cppu::OMultiTypeInterfaceContainerHelper::keyType
> ( m_aLock
.getShareableOslMutex() )
207 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper
* >(this)) )
208 , ::cppu::OWeakObject ( )
210 #ifdef ENABLE_ASSERTIONS
211 , m_bIsTerminated ( sal_False
) // see dispose() for further information!
213 , m_xFactory ( xFactory
)
214 , m_aChildTaskContainer ( )
215 , m_aListenerContainer ( m_aLock
.getShareableOslMutex() )
216 , m_xFramesHelper ( )
217 , m_xDispatchHelper ( )
218 , m_eLoadState ( E_NOTSET
)
220 , m_aInteractionRequest ( )
221 , m_bSuspendQuickstartVeto( sal_False
)
222 , m_aCommandOptions ( )
225 , m_xDispatchRecorderSupplier( )
226 , m_xPipeTerminator ( )
227 , m_xQuickLauncher ( )
228 , m_xSWThreadManager ( )
229 , m_xSfxTerminator ( )
230 , m_xTitleNumberGenerator ( )
232 // Safe impossible cases
233 // We don't accept all incoming parameter.
234 LOG_ASSERT2( implcp_ctor( xFactory
), "Desktop::Desktop()", "Invalid parameter detected!")
237 /*-************************************************************************************************************//**
238 @short standard destructor
239 @descr This one do NOTHING! Use dispose() instaed of this.
241 @seealso method dispose()
247 *//*-*************************************************************************************************************/
250 #ifdef ENABLE_ASSERTIONS
251 // Perhaps we should here do use a real assertion, but make the
252 // condition more specific? We don't want it to fire in unit tests
253 // in sc/qa/unit for instance, that don't even have any GUI.
254 if( !m_bIsTerminated
)
255 fprintf( stderr
, "This used to be an assertion failure: Desktop not terminated before being destructed,\n"
256 "but it is probably not a real problem.\n" );
258 LOG_ASSERT2( m_aTransactionManager
.getWorkingMode()!=E_CLOSE
, "Desktop::~Desktop()", "Who forgot to dispose this service?" )
261 //=============================================================================
262 sal_Bool SAL_CALL
Desktop::terminate()
263 throw( css::uno::RuntimeException
)
265 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
267 ReadGuard
aReadLock( m_aLock
); // start synchronize
269 css::uno::Reference
< css::frame::XTerminateListener
> xPipeTerminator
= m_xPipeTerminator
;
270 css::uno::Reference
< css::frame::XTerminateListener
> xQuickLauncher
= m_xQuickLauncher
;
271 css::uno::Reference
< css::frame::XTerminateListener
> xSWThreadManager
= m_xSWThreadManager
;
272 css::uno::Reference
< css::frame::XTerminateListener
> xSfxTerminator
= m_xSfxTerminator
;
274 css::lang::EventObject
aEvent ( static_cast< ::cppu::OWeakObject
* >(this) );
275 ::sal_Bool bAskQuickStart
= !m_bSuspendQuickstartVeto
;
277 aReadLock
.unlock(); // end synchronize
279 //-------------------------------------------------------------------------------------------------------------
280 // Ask normal terminate listener. They could stop terminate without closing any open document.
281 Desktop::TTerminateListenerList lCalledTerminationListener
;
282 ::sal_Bool bVeto
= sal_False
;
283 impl_sendQueryTerminationEvent(lCalledTerminationListener
, bVeto
);
286 impl_sendCancelTerminationEvent(lCalledTerminationListener
);
290 //-------------------------------------------------------------------------------------------------------------
291 // try to close all open frames.
292 // Allow using of any UI ... because Desktop.terminate() was designed as UI functionality in the past.
293 ::sal_Bool bAllowUI
= sal_True
;
294 ::sal_Bool bFramesClosed
= impl_closeFrames(bAllowUI
);
295 if ( ! bFramesClosed
)
297 impl_sendCancelTerminationEvent(lCalledTerminationListener
);
301 //-------------------------------------------------------------------------------------------------------------
302 // Normal listener had no problem ...
303 // all frames was closed ...
304 // now it's time to ask our specialized listener.
305 // They are handled these way because they wish to hinder the office on termination
306 // but they wish also closing of all frames.
309 // We shouldn't ask quicklauncher in case it was allowed from outside only.
310 // This is special trick to "ignore existing quick starter" for debug purposes.
313 // Order of alled listener is important !
314 // some of them are harmless .-)
315 // But some of them can be dangerous. E.g. it would be dangerous if we close our pipe
316 // and dont terminate in real because another listener throws a veto exception .-)
318 ::sal_Bool bTerminate
= sal_False
;
322 ( bAskQuickStart
) &&
323 ( xQuickLauncher
.is() )
326 xQuickLauncher
->queryTermination( aEvent
);
327 lCalledTerminationListener
.push_back( xQuickLauncher
);
330 if ( xSWThreadManager
.is() )
332 xSWThreadManager
->queryTermination( aEvent
);
333 lCalledTerminationListener
.push_back( xSWThreadManager
);
336 if ( xPipeTerminator
.is() )
338 xPipeTerminator
->queryTermination( aEvent
);
339 lCalledTerminationListener
.push_back( xPipeTerminator
);
342 if ( xSfxTerminator
.is() )
344 xSfxTerminator
->queryTermination( aEvent
);
345 lCalledTerminationListener
.push_back( xSfxTerminator
);
348 bTerminate
= sal_True
;
350 catch(const css::frame::TerminationVetoException
&)
352 bTerminate
= sal_False
;
356 impl_sendCancelTerminationEvent(lCalledTerminationListener
);
359 #ifdef ENABLE_ASSERTIONS
360 // "Protect" us against dispose before terminate calls!
361 // see dispose() for further information.
362 /* SAFE AREA --------------------------------------------------------------------------------------- */
363 WriteGuard
aWriteLock( m_aLock
);
364 m_bIsTerminated
= sal_True
;
366 /* UNSAFE AREA ------------------------------------------------------------------------------------- */
369 impl_sendNotifyTerminationEvent();
372 ( bAskQuickStart
) &&
373 ( xQuickLauncher
.is() )
376 xQuickLauncher
->notifyTermination( aEvent
);
379 if ( xSWThreadManager
.is() )
380 xSWThreadManager
->notifyTermination( aEvent
);
382 if ( xPipeTerminator
.is() )
383 xPipeTerminator
->notifyTermination( aEvent
);
385 // Must be realy the last listener to be called.
386 // Because it shutdown the whole process asynchronous !
387 if ( xSfxTerminator
.is() )
388 xSfxTerminator
->notifyTermination( aEvent
);
396 class QuickstartSuppressor
398 Desktop
* const m_pDesktop
;
399 css::uno::Reference
< css::frame::XTerminateListener
> m_xQuickLauncher
;
401 QuickstartSuppressor(Desktop
* const pDesktop
, css::uno::Reference
< css::frame::XTerminateListener
> xQuickLauncher
)
402 : m_pDesktop(pDesktop
)
403 , m_xQuickLauncher(xQuickLauncher
)
405 SAL_INFO("fwk.desktop", "temporary removing Quickstarter");
406 if(m_xQuickLauncher
.is())
407 m_pDesktop
->removeTerminateListener(m_xQuickLauncher
);
409 ~QuickstartSuppressor()
411 SAL_INFO("fwk.desktop", "readding Quickstarter");
412 if(m_xQuickLauncher
.is())
413 m_pDesktop
->addTerminateListener(m_xQuickLauncher
);
418 bool SAL_CALL
Desktop::terminateQuickstarterToo()
419 throw( css::uno::RuntimeException
)
421 QuickstartSuppressor
aQuickstartSuppressor(this, m_xQuickLauncher
);
425 //=============================================================================
426 void SAL_CALL
Desktop::addTerminateListener( const css::uno::Reference
< css::frame::XTerminateListener
>& xListener
)
427 throw( css::uno::RuntimeException
)
429 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
431 css::uno::Reference
< css::lang::XServiceInfo
> xInfo( xListener
, css::uno::UNO_QUERY
);
434 OUString sImplementationName
= xInfo
->getImplementationName();
437 WriteGuard
aWriteLock( m_aLock
);
439 if( sImplementationName
.equals(IMPLEMENTATIONNAME_SFXTERMINATOR
) )
441 m_xSfxTerminator
= xListener
;
444 if( sImplementationName
.equals(IMPLEMENTATIONNAME_PIPETERMINATOR
) )
446 m_xPipeTerminator
= xListener
;
449 if( sImplementationName
.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER
) )
451 m_xQuickLauncher
= xListener
;
454 if( sImplementationName
.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER
) )
456 m_xSWThreadManager
= xListener
;
464 // No lock required ... container is threadsafe by itself.
465 m_aListenerContainer
.addInterface( ::getCppuType( ( const css::uno::Reference
< css::frame::XTerminateListener
>*) NULL
), xListener
);
468 //=============================================================================
469 void SAL_CALL
Desktop::removeTerminateListener( const css::uno::Reference
< css::frame::XTerminateListener
>& xListener
)
470 throw( css::uno::RuntimeException
)
472 TransactionGuard
aTransaction( m_aTransactionManager
, E_SOFTEXCEPTIONS
);
474 css::uno::Reference
< css::lang::XServiceInfo
> xInfo( xListener
, css::uno::UNO_QUERY
);
477 OUString sImplementationName
= xInfo
->getImplementationName();
480 WriteGuard
aWriteLock( m_aLock
);
482 if( sImplementationName
.equals(IMPLEMENTATIONNAME_SFXTERMINATOR
) )
484 m_xSfxTerminator
.clear();
488 if( sImplementationName
.equals(IMPLEMENTATIONNAME_PIPETERMINATOR
) )
490 m_xPipeTerminator
.clear();
494 if( sImplementationName
.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER
) )
496 m_xQuickLauncher
.clear();
500 if( sImplementationName
.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER
) )
502 m_xSWThreadManager
.clear();
510 // No lock required ... container is threadsafe by itself.
511 m_aListenerContainer
.removeInterface( ::getCppuType( ( const css::uno::Reference
< css::frame::XTerminateListener
>*) NULL
), xListener
);
514 /*-************************************************************************************************************//**
516 @short get access to create enumerations of all current components
517 @descr You will be the owner of the returned object and must delete it if you don't use it again.
519 @seealso class TasksAccess
520 @seealso class TasksEnumeration
523 @return A reference to an XEnumerationAccess-object.
525 @onerror We return a null-reference.
527 *//*-*************************************************************************************************************/
528 css::uno::Reference
< css::container::XEnumerationAccess
> SAL_CALL
Desktop::getComponents() throw( css::uno::RuntimeException
)
530 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
531 // Register transaction and reject wrong calls.
532 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
534 // We use a helper class OComponentAccess to have access on all child components.
535 // Create it on demand and return it as a reference.
536 OComponentAccess
* pAccess
= new OComponentAccess( this );
537 css::uno::Reference
< css::container::XEnumerationAccess
> xAccess( static_cast< ::cppu::OWeakObject
* >(pAccess
), css::uno::UNO_QUERY
);
541 /*-************************************************************************************************************//**
543 @short return the current active component
544 @descr The most current component is the window, model or the controller of the current active frame.
546 @seealso method getCurrentFrame()
547 @seealso method impl_getFrameComponent()
550 @return A reference to the component.
552 @onerror We return a null-reference.
554 *//*-*************************************************************************************************************/
555 css::uno::Reference
< css::lang::XComponent
> SAL_CALL
Desktop::getCurrentComponent() throw( css::uno::RuntimeException
)
557 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
558 // Register transaction and reject wrong calls.
559 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
561 // Set return value if method failed.
562 css::uno::Reference
< css::lang::XComponent
> xComponent
;
564 // Get reference to current frame ...
565 // ... get component of this frame ... (It can be the window, the model or the controller.)
566 // ... and return the result.
567 css::uno::Reference
< css::frame::XFrame
> xCurrentFrame
= getCurrentFrame();
568 if( xCurrentFrame
.is() == sal_True
)
570 xComponent
= impl_getFrameComponent( xCurrentFrame
);
575 /*-************************************************************************************************************//**
577 @short return the current active frame in hierarchy
578 @descr There can be more then one different active paths in our frame hierarchy. But only one of them
579 could be the most active frame (normal he has the focus).
580 Don't mix it with getActiveFrame()! That will return our current active frame, which must be
581 a direct child of us and should be a part(!) of an active path.
583 @seealso method getActiveFrame()
586 @return A valid reference, if there is an active frame.
587 A null reference , otherwise.
589 @onerror We return a null reference.
591 *//*-*************************************************************************************************************/
592 css::uno::Reference
< css::frame::XFrame
> SAL_CALL
Desktop::getCurrentFrame() throw( css::uno::RuntimeException
)
594 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
595 // Register transaction and reject wrong calls.
596 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
598 // Start search with ouer direct active frame (if it exist!).
599 // Search on his children for other active frames too.
600 // Stop if no one could be found and return last of found ones.
601 css::uno::Reference
< css::frame::XFramesSupplier
> xLast
= css::uno::Reference
< css::frame::XFramesSupplier
>( getActiveFrame(), css::uno::UNO_QUERY
);
602 if( xLast
.is() == sal_True
)
604 css::uno::Reference
< css::frame::XFramesSupplier
> xNext
= css::uno::Reference
< css::frame::XFramesSupplier
>( xLast
->getActiveFrame(), css::uno::UNO_QUERY
);
605 while( xNext
.is() == sal_True
)
608 xNext
= css::uno::Reference
< css::frame::XFramesSupplier
>( xNext
->getActiveFrame(), css::uno::UNO_QUERY
);
611 return css::uno::Reference
< css::frame::XFrame
>( xLast
, css::uno::UNO_QUERY
);
614 /*-************************************************************************************************************//**
615 @interface XComponentLoader
616 @short try to load given URL into a task
617 @descr You can give us some information about the content, which you will load into a frame.
618 We search or create this target for you, make a type detection of given URL and try to load it.
619 As result of this operation we return the new created component or nothing, if loading failed.
623 @param "sURL" , URL, which represant the content
624 @param "sTargetFrameName" , name of target frame or special value like "_self", "_blank" ...
625 @param "nSearchFlags" , optional arguments for frame search, if target isn't a special one
626 @param "lArguments" , optional arguments for loading
627 @return A valid component reference, if loading was successfully.
628 A null reference otherwise.
630 @onerror We return a null reference.
632 *//*-*************************************************************************************************************/
633 css::uno::Reference
< css::lang::XComponent
> SAL_CALL
Desktop::loadComponentFromURL( const OUString
& sURL
,
634 const OUString
& sTargetFrameName
,
635 sal_Int32 nSearchFlags
,
636 const css::uno::Sequence
< css::beans::PropertyValue
>& lArguments
) throw( css::io::IOException
,
637 css::lang::IllegalArgumentException
,
638 css::uno::RuntimeException
)
640 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
641 // Register transaction and reject wrong calls.
642 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
643 RTL_LOGFILE_CONTEXT( aLog
, "framework (as96863) ::Desktop::loadComponentFromURL" );
645 ReadGuard
aReadLock(m_aLock
);
646 css::uno::Reference
< css::frame::XComponentLoader
> xThis(static_cast< css::frame::XComponentLoader
* >(this), css::uno::UNO_QUERY
);
647 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xFactory
;
650 RTL_LOGFILE_PRODUCT_CONTEXT( aLog2
, "PERFORMANCE - Desktop::loadComponentFromURL()" );
651 return LoadEnv::loadComponentFromURL(xThis
, xSMGR
, sURL
, sTargetFrameName
, nSearchFlags
, lArguments
);
654 /*-************************************************************************************************************//**
655 @interface XTasksSupplier
656 @short get access to create enumerations of ouer taskchildren
657 @descr Direct children of desktop are tasks everytime.
658 Call these method to could create enumerations of it.
660 But; Don't forget - you will be the owner of returned object and must release it!
661 We use a helper class to implement the access interface. They hold a weakreference to us.
662 It can be, that the desktop is dead - but not your tasksaccess-object! Then they will do nothing!
663 You can't create enumerations then.
665 @attention Normaly we don't need any lock here. We don't work on internal member!
667 @seealso class TasksAccess
670 @return A reference to an accessobject, which can create enumerations of ouer childtasks.
672 @onerror A null reference is returned.
674 *//*-*************************************************************************************************************/
675 css::uno::Reference
< css::container::XEnumerationAccess
> SAL_CALL
Desktop::getTasks() throw( css::uno::RuntimeException
)
677 LOG_WARNING("Desktop::getTasks()", "Use of obsolete interface XTaskSupplier")
681 /*-************************************************************************************************************//**
682 @interface XTasksSupplier
683 @short return current active task of ouer direct children
684 @descr Desktop children are tasks only ! If we have an active path from desktop
685 as top to any frame on bottom, we must have an active direct child. His reference is returned here.
687 @attention a) Do not confuse it with getCurrentFrame()! The current frame don't must one of ouer direct children.
688 It can be every frame in subtree and must have the focus (Is the last one of an active path!).
689 b) We don't need any lock here. Our container is threadsafe himself and live, if we live!
691 @seealso method getCurrentFrame()
694 @return A reference to ouer current active taskchild.
696 @onerror A null reference is returned.
698 *//*-*************************************************************************************************************/
699 css::uno::Reference
< css::frame::XTask
> SAL_CALL
Desktop::getActiveTask() throw( css::uno::RuntimeException
)
701 LOG_WARNING("Desktop::getActiveTask()", "Use of obsolete interface XTaskSupplier")
705 /*-************************************************************************************************************//**
706 @interface XDispatchProvider
707 @short search a dispatcher for given URL
708 @descr We use a helper implementation (class DispatchProvider) to do so.
709 So we don't must implement this algorithm twice!
711 @attention We don't need any lock here. Our helper is threadsafe himself and live, if we live!
713 @seealso class DispatchProvider
715 @param "aURL" , URL to dispatch
716 @param "sTargetFrameName" , name of target frame, who should dispatch these URL
717 @param "nSearchFlags" , flags to regulate the search
718 @param "lQueries" , list of queryDispatch() calls!
719 @return A reference or list of founded dispatch objects for these URL.
721 @onerror A null reference is returned.
723 *//*-*************************************************************************************************************/
724 css::uno::Reference
< css::frame::XDispatch
> SAL_CALL
Desktop::queryDispatch( const css::util::URL
& aURL
,
725 const OUString
& sTargetFrameName
,
726 sal_Int32 nSearchFlags
) throw( css::uno::RuntimeException
)
728 const char UNO_PROTOCOL
[] = ".uno:";
730 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
731 // Register transaction and reject wrong calls.
732 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
734 // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
735 // in our hash map. All other protocols are stored with the protocol part.
736 String
aCommand( aURL
.Main
);
737 if ( aURL
.Protocol
.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL
, sizeof( UNO_PROTOCOL
)-1 ))
738 aCommand
= aURL
.Path
;
740 // Make boost::unordered_map lookup if the current URL is in the disabled list
741 if ( m_aCommandOptions
.Lookup( SvtCommandOptions::CMDOPTION_DISABLED
, aCommand
) )
742 return css::uno::Reference
< css::frame::XDispatch
>();
745 // We use a helper to support these interface and an interceptor mechanism.
746 // Our helper is threadsafe by himself!
747 return m_xDispatchHelper
->queryDispatch( aURL
, sTargetFrameName
, nSearchFlags
);
751 //*****************************************************************************************************************
752 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
)
754 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
755 // Register transaction and reject wrong calls.
756 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
758 return m_xDispatchHelper
->queryDispatches( lQueries
);
761 /*-************************************************************************************************************//**
762 @interface XDipsatchProviderInterception
763 @short supports registration/deregistration of interception objects, which
764 are interested on special dispatches.
766 @descr Its realy provided by an internal helper, which is used inside the dispatch api too.
768 the interceptor object, which wish to be (de)registered.
771 *//*-*************************************************************************************************************/
772 void SAL_CALL
Desktop::registerDispatchProviderInterceptor( const css::uno::Reference
< css::frame::XDispatchProviderInterceptor
>& xInterceptor
)
773 throw( css::uno::RuntimeException
)
775 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
777 css::uno::Reference
< css::frame::XDispatchProviderInterception
> xInterceptionHelper( m_xDispatchHelper
, css::uno::UNO_QUERY
);
778 xInterceptionHelper
->registerDispatchProviderInterceptor( xInterceptor
);
781 //*****************************************************************************************************************
782 void SAL_CALL
Desktop::releaseDispatchProviderInterceptor ( const css::uno::Reference
< css::frame::XDispatchProviderInterceptor
>& xInterceptor
)
783 throw( css::uno::RuntimeException
)
785 TransactionGuard
aTransaction( m_aTransactionManager
, E_SOFTEXCEPTIONS
);
787 css::uno::Reference
< css::frame::XDispatchProviderInterception
> xInterceptionHelper( m_xDispatchHelper
, css::uno::UNO_QUERY
);
788 xInterceptionHelper
->releaseDispatchProviderInterceptor( xInterceptor
);
791 /*-************************************************************************************************************//**
792 @interface XFramesSupplier
793 @short return access to append or remove children on desktop
794 @descr We don't implement these interface directly. We use a helper class to do this.
795 If you wish to add or delete children to/from the container, call these method to get
796 a reference to the helper.
798 @attention Helper is threadsafe himself. So we don't need any lock here.
800 @seealso class OFrames
803 @return A reference to the helper.
805 @onerror A null reference is returned.
807 *//*-*************************************************************************************************************/
808 css::uno::Reference
< css::frame::XFrames
> SAL_CALL
Desktop::getFrames() throw( css::uno::RuntimeException
)
810 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
811 // Register transaction and reject wrong calls.
812 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
814 return m_xFramesHelper
;
817 /*-************************************************************************************************************//**
818 @interface XFramesSupplier
819 @short set/get the current active child frame
820 @descr It must be a task. Direct children of desktop are tasks only! No frames are accepted.
821 We don't save this information directly in this class. We use ouer container-helper
824 @attention Helper is threadsafe himself. So we don't need any lock here.
826 @seealso class OFrameContainer
828 @param "xFrame", new active frame (must be valid!)
829 @return A reference to ouer current active childtask, if anyone exist.
831 @onerror A null reference is returned.
833 *//*-*************************************************************************************************************/
834 void SAL_CALL
Desktop::setActiveFrame( const css::uno::Reference
< css::frame::XFrame
>& xFrame
) throw( css::uno::RuntimeException
)
836 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
837 // Register transaction and reject wrong calls.
838 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
840 // Get old active frame first.
841 // If nothing will change - do nothing!
842 // Otherwise set new active frame ...
843 // and deactivate last frame.
844 // It's necessary for our FrameActionEvent listener on a frame!
845 css::uno::Reference
< css::frame::XFrame
> xLastActiveChild
= m_aChildTaskContainer
.getActive();
846 if( xLastActiveChild
!= xFrame
)
848 m_aChildTaskContainer
.setActive( xFrame
);
849 if( xLastActiveChild
.is() == sal_True
)
851 xLastActiveChild
->deactivate();
856 //*****************************************************************************************************************
857 css::uno::Reference
< css::frame::XFrame
> SAL_CALL
Desktop::getActiveFrame() throw( css::uno::RuntimeException
)
859 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
860 // Register transaction and reject wrong calls.
861 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
863 return m_aChildTaskContainer
.getActive();
866 /*-************************************************************************************************************//**
868 @short non implemented methods!
869 @descr Some method make no sense for our desktop! He has no window or parent or ...
870 So we should implement it empty and warn programmer, if he use it!
879 *//*-*************************************************************************************************************/
880 void SAL_CALL
Desktop::initialize( const css::uno::Reference
< css::awt::XWindow
>& ) throw( css::uno::RuntimeException
)
884 //*****************************************************************************************************************
885 css::uno::Reference
< css::awt::XWindow
> SAL_CALL
Desktop::getContainerWindow() throw( css::uno::RuntimeException
)
887 return css::uno::Reference
< css::awt::XWindow
>();
890 //*****************************************************************************************************************
891 void SAL_CALL
Desktop::setCreator( const css::uno::Reference
< css::frame::XFramesSupplier
>& /*xCreator*/ ) throw( css::uno::RuntimeException
)
895 //*****************************************************************************************************************
896 css::uno::Reference
< css::frame::XFramesSupplier
> SAL_CALL
Desktop::getCreator() throw( css::uno::RuntimeException
)
898 return css::uno::Reference
< css::frame::XFramesSupplier
>();
901 //*****************************************************************************************************************
902 OUString SAL_CALL
Desktop::getName() throw( css::uno::RuntimeException
)
905 ReadGuard
aReadLock( m_aLock
);
910 //*****************************************************************************************************************
911 void SAL_CALL
Desktop::setName( const OUString
& sName
) throw( css::uno::RuntimeException
)
914 WriteGuard
aWriteLock( m_aLock
);
920 //*****************************************************************************************************************
921 sal_Bool SAL_CALL
Desktop::isTop() throw( css::uno::RuntimeException
)
926 //*****************************************************************************************************************
927 void SAL_CALL
Desktop::activate() throw( css::uno::RuntimeException
)
929 // Desktop is activae always ... but sometimes our frames try to activate
930 // the complete path from bottom to top ... And our desktop is the topest frame :-(
931 // So - please don't show any assertions here. Do nothing!
934 //*****************************************************************************************************************
935 void SAL_CALL
Desktop::deactivate() throw( css::uno::RuntimeException
)
937 // Desktop is activae always ... but sometimes our frames try to deactivate
938 // the complete path from bottom to top ... And our desktop is the topest frame :-(
939 // So - please don't show any assertions here. Do nothing!
942 //*****************************************************************************************************************
943 sal_Bool SAL_CALL
Desktop::isActive() throw( css::uno::RuntimeException
)
948 //*****************************************************************************************************************
949 sal_Bool SAL_CALL
Desktop::setComponent( const css::uno::Reference
< css::awt::XWindow
>& /*xComponentWindow*/ ,
950 const css::uno::Reference
< css::frame::XController
>& /*xController*/ ) throw( css::uno::RuntimeException
)
955 //*****************************************************************************************************************
956 css::uno::Reference
< css::awt::XWindow
> SAL_CALL
Desktop::getComponentWindow() throw( css::uno::RuntimeException
)
958 return css::uno::Reference
< css::awt::XWindow
>();
961 //*****************************************************************************************************************
962 css::uno::Reference
< css::frame::XController
> SAL_CALL
Desktop::getController() throw( css::uno::RuntimeException
)
964 return css::uno::Reference
< css::frame::XController
>();
967 //*****************************************************************************************************************
968 void SAL_CALL
Desktop::contextChanged() throw( css::uno::RuntimeException
)
972 //*****************************************************************************************************************
973 void SAL_CALL
Desktop::addFrameActionListener( const css::uno::Reference
< css::frame::XFrameActionListener
>& ) throw( css::uno::RuntimeException
)
977 //*****************************************************************************************************************
978 // css::frame::XFrame
979 //*****************************************************************************************************************
980 void SAL_CALL
Desktop::removeFrameActionListener( const css::uno::Reference
< css::frame::XFrameActionListener
>& ) throw( css::uno::RuntimeException
)
984 /*-************************************************************************************************************//**
986 @short try to find a frame with special parameters
987 @descr This method searches for a frame with the specified name.
988 Frames may contain other frames (e.g. a frameset) and may
989 be contained in other frames. This hierarchie ist searched by
991 First some special names are taken into account, i.e. "",
992 "_self", "_top", "_parent" etc. The FrameSearchFlags are ignored
993 when comparing these names with aTargetFrameName, further steps are
994 controlled by the FrameSearchFlags. If allowed, the name of the frame
995 itself is compared with the desired one, then ( again if allowed )
996 the method findFrame is called for all children of the frame.
997 If no Frame with the given name is found until the top frames container,
998 a new top Frame is created, if this is allowed by a special
999 FrameSearchFlag. The new Frame also gets the desired name.
1000 We use a helper to get right search direction and react in a right manner.
1002 @seealso class TargetFinder
1004 @param "sTargetFrameName" , name of searched frame
1005 @param "nSearchFlags" , flags to regulate search
1006 @return A reference to an existing frame in hierarchy, if it exist.
1008 @onerror A null reference is returned.
1010 *//*-*************************************************************************************************************/
1011 css::uno::Reference
< css::frame::XFrame
> SAL_CALL
Desktop::findFrame( const OUString
& sTargetFrameName
,
1012 sal_Int32 nSearchFlags
) throw( css::uno::RuntimeException
)
1014 css::uno::Reference
< css::frame::XFrame
> xTarget
;
1016 //-----------------------------------------------------------------------------------------------------
1017 // 0) Ignore wrong parameter!
1018 // We doesn't support search for following special targets.
1019 // If we reject this requests - we mustnt check for such names
1020 // in following code again and again. If we do not so -wrong
1021 // search results can occure!
1022 //-----------------------------------------------------------------------------------------------------
1024 (sTargetFrameName
==SPECIALTARGET_DEFAULT
) || // valid for dispatches - not for findFrame()!
1025 (sTargetFrameName
==SPECIALTARGET_MENUBAR
) || // valid for dispatches - not for findFrame()!
1026 (sTargetFrameName
==SPECIALTARGET_PARENT
) || // we have no parent by definition
1027 (sTargetFrameName
==SPECIALTARGET_BEAMER
) // beamer frames are allowed as child of tasks only -
1028 // and they exist more then ones. We have no idea which our sub tasks is the right one
1034 //-----------------------------------------------------------------------------------------------------
1035 // I) check for special defined targets first which must be handled exclusive.
1036 // force using of "if() else if() ..."
1037 //-----------------------------------------------------------------------------------------------------
1039 // get threadsafe some necessary member which are neccessary for following functionality
1041 ReadGuard
aReadLock( m_aLock
);
1042 css::uno::Reference
< css::lang::XMultiServiceFactory
> xFactory
= m_xFactory
;
1046 //-----------------------------------------------------------------------------------------------------
1048 // create a new task as child of this desktop instance
1049 // Note: Used helper TaskCreator use us automaticly ...
1050 //-----------------------------------------------------------------------------------------------------
1051 if ( sTargetFrameName
==SPECIALTARGET_BLANK
)
1053 TaskCreator
aCreator(xFactory
);
1054 xTarget
= aCreator
.createTask(sTargetFrameName
,sal_False
);
1057 //-----------------------------------------------------------------------------------------------------
1059 // We are top by definition
1060 //-----------------------------------------------------------------------------------------------------
1061 else if ( sTargetFrameName
==SPECIALTARGET_TOP
)
1066 //-----------------------------------------------------------------------------------------------------
1067 // I.III) "_self", ""
1068 // This mean this "frame" in every case.
1069 //-----------------------------------------------------------------------------------------------------
1071 ( sTargetFrameName
==SPECIALTARGET_SELF
) ||
1072 ( sTargetFrameName
.isEmpty() )
1080 //-------------------------------------------------------------------------------------------------
1081 // II) otherwise use optional given search flags
1082 // force using of combinations of such flags. means no "else" part of use if() statements.
1083 // But we ust break further searches if target was already found.
1084 // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
1085 // TASK and CREATE are handled special.
1086 // But note: Such flags are not valid for the desktop - especialy SIBLINGS or PARENT.
1087 //-------------------------------------------------------------------------------------------------
1089 // get threadsafe some necessary member which are neccessary for following functionality
1092 OUString sOwnName
= m_sName
;
1096 //-------------------------------------------------------------------------------------------------
1098 // Check for right name. If it's the searched one return ourself - otherwise
1099 // ignore this flag.
1100 //-------------------------------------------------------------------------------------------------
1102 (nSearchFlags
& css::frame::FrameSearchFlag::SELF
) &&
1103 (sOwnName
== sTargetFrameName
)
1109 //-------------------------------------------------------------------------------------------------
1111 // This is a special flag. Normaly it regulate search inside tasks and forbid access to parent trees.
1112 // But the desktop exists outside such task trees. They are our sub trees. So the desktop implement
1113 // a special feature: We use it to start search on our direct children only. That means we supress
1114 // search on ALL child frames. May that can be useful to get access on opened document tasks
1115 // only without filter out all non realy required sub frames ...
1116 // Used helper method on our container doesn't create any frame - its a search only.
1117 //-------------------------------------------------------------------------------------------------
1119 ( ! xTarget
.is() ) &&
1120 (nSearchFlags
& css::frame::FrameSearchFlag::TASKS
)
1123 xTarget
= m_aChildTaskContainer
.searchOnDirectChildrens(sTargetFrameName
);
1126 //-------------------------------------------------------------------------------------------------
1128 // Search on all children for the given target name.
1129 // An empty name value can't occure here - because it must be already handled as "_self"
1130 // before. Used helper function of container doesn't create any frame.
1131 // It makes a deep search only.
1132 //-------------------------------------------------------------------------------------------------
1134 ( ! xTarget
.is() ) &&
1135 (nSearchFlags
& css::frame::FrameSearchFlag::CHILDREN
)
1138 xTarget
= m_aChildTaskContainer
.searchOnAllChildrens(sTargetFrameName
);
1141 //-------------------------------------------------------------------------------------------------
1143 // If we haven't found any valid target frame by using normal flags - but user allowed us to create
1144 // a new one ... we should do that. Used TaskCreator use us automaticly as parent!
1145 //-------------------------------------------------------------------------------------------------
1147 ( ! xTarget
.is() ) &&
1148 (nSearchFlags
& css::frame::FrameSearchFlag::CREATE
)
1151 TaskCreator
aCreator(xFactory
);
1152 xTarget
= aCreator
.createTask(sTargetFrameName
,sal_False
);
1159 //=============================================================================
1160 void SAL_CALL
Desktop::dispose()
1161 throw( css::uno::RuntimeException
)
1163 // Safe impossible cases
1164 // It's an programming error if dispose is called before terminate!
1166 // But if you just ignore the assertion (which happens in unit
1167 // tests for instance in sc/qa/unit) nothing bad happens.
1168 #ifdef ENABLE_ASSERTIONS
1169 if( !m_bIsTerminated
)
1170 fprintf( stderr
, "This used to be an assertion failure: Desktop disposed before terminating it,\n"
1171 "but nothing bad seems to happen anyway?\n" );
1174 WriteGuard
aWriteLock( m_aLock
); // start synchronize
1176 // Look for multiple calls of this method!
1177 // If somewhere call dispose() twice - he will be stopped here realy!!!
1178 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1180 // Now - we are alone and its the first call of this method ...
1181 // otherwise call before had thrown a DisposedException / hopefully .-)
1182 // But we dont use the transaction object created before ... we reset it immediately ...
1183 // two lines of code ... for what ?
1184 // The answer: We wished to synchronize concurrent dispose() calls -> OK
1185 // But next line will wait for all currently running transaction (even if they
1186 // are running within the same thread!) So we would block ourself there if aTransaction
1187 // will stay registered .-)
1188 aTransaction
.stop();
1190 // Disable this instance for further work.
1191 // This will wait for all current running transactions ...
1192 // and reject all new incoming requests!
1193 m_aTransactionManager
.setWorkingMode( E_BEFORECLOSE
);
1195 aWriteLock
.unlock(); // end synchronize
1197 // Following lines of code can be called outside a synchronized block ...
1198 // Because our transaction manager will block all new requests to this object.
1199 // So nobody can use us any longer.
1200 // Exception: Only removing of listener will work ... and this code cant be dangerous.
1202 // First we has to kill all listener connections.
1203 // They might rely on our member and can hinder us on releasing them.
1204 css::uno::Reference
< css::uno::XInterface
> xThis ( static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
1205 css::lang::EventObject
aEvent( xThis
);
1206 m_aListenerContainer
.disposeAndClear( aEvent
);
1208 // Clear our child task container and forget all task references hardly.
1209 // Normaly all open document was already closed by our terminate() function before ...
1210 // New opened frames will have a problem now .-)
1211 m_aChildTaskContainer
.clear();
1213 // Dispose our helper too.
1214 css::uno::Reference
< css::lang::XEventListener
> xFramesHelper( m_xFramesHelper
, css::uno::UNO_QUERY
);
1215 if( xFramesHelper
.is() )
1216 xFramesHelper
->disposing( aEvent
);
1218 // At least clean up other member references.
1219 m_xDispatchHelper
.clear();
1220 m_xFramesHelper
.clear();
1221 m_xLastFrame
.clear();
1224 m_xPipeTerminator
.clear();
1225 m_xQuickLauncher
.clear();
1226 m_xSWThreadManager
.clear();
1227 m_xSfxTerminator
.clear();
1229 // From this point nothing will work further on this object ...
1230 // excepting our dtor() .-)
1231 m_aTransactionManager
.setWorkingMode( E_CLOSE
);
1234 /*-************************************************************************************************************//**
1235 @interface XComponent
1236 @short add/remove listener for dispose events
1237 @descr Add an event listener to this object, if you whish to get information
1239 You must releas ethis listener reference during your own disposing() method.
1241 @attention Our container is threadsafe himeslf. So we doesn't need any lock here.
1245 @param "xListener", reference to valid listener. We don't accept invalid values!
1250 *//*-*************************************************************************************************************/
1251 void SAL_CALL
Desktop::addEventListener( const css::uno::Reference
< css::lang::XEventListener
>& xListener
) throw( css::uno::RuntimeException
)
1253 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1254 // Safe impossible cases
1255 // Method not defined for all incoming parameter.
1256 LOG_ASSERT2( implcp_addEventListener( xListener
), "Desktop::addEventListener()", "Invalid parameter detected!" )
1257 // Register transaction and reject wrong calls.
1258 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1260 m_aListenerContainer
.addInterface( ::getCppuType( ( const css::uno::Reference
< css::lang::XEventListener
>*) NULL
), xListener
);
1263 //*****************************************************************************************************************
1264 void SAL_CALL
Desktop::removeEventListener( const css::uno::Reference
< css::lang::XEventListener
>& xListener
) throw( css::uno::RuntimeException
)
1266 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1267 // Safe impossible cases
1268 // Method not defined for all incoming parameter.
1269 LOG_ASSERT2( implcp_removeEventListener( xListener
), "Desktop::removeEventListener()", "Invalid parameter detected!" )
1270 // Register transaction and reject wrong calls.
1271 TransactionGuard
aTransaction( m_aTransactionManager
, E_SOFTEXCEPTIONS
);
1273 m_aListenerContainer
.removeInterface( ::getCppuType( ( const css::uno::Reference
< css::lang::XEventListener
>*) NULL
), xListener
);
1276 /*-************************************************************************************************************//**
1277 @interface XDispatchResultListener
1278 @short callback for dispatches
1279 @descr To support our method "loadComponentFromURL()" we are listener on temp. created dispatcher.
1280 They call us back in this method "statusChanged()". As source of given state event, they give us a
1281 reference to the target frame, in which dispatch was loaded! So we can use it to return his component
1282 to caller! If no target exist ... ??!!
1284 @seealso method loadComponentFromURL()
1286 @param "aEvent", state event which (hopefully) valid information
1291 *//*-*************************************************************************************************************/
1292 void SAL_CALL
Desktop::dispatchFinished( const css::frame::DispatchResultEvent
& aEvent
) throw( css::uno::RuntimeException
)
1294 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1295 // Register transaction and reject wrong calls.
1296 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1298 /* SAFE AREA ------------------------------------------------------------------------------------------- */
1299 WriteGuard
aWriteLock( m_aLock
);
1300 if( m_eLoadState
!= E_INTERACTION
)
1302 m_xLastFrame
= css::uno::Reference
< css::frame::XFrame
>();
1303 m_eLoadState
= E_FAILED
;
1304 if( aEvent
.State
== css::frame::DispatchResultState::SUCCESS
)
1306 css::uno::Reference
< css::frame::XFrame
> xFrame
;
1307 if ( aEvent
.Result
>>= m_xLastFrame
)
1308 m_eLoadState
= E_SUCCESSFUL
;
1311 /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
1314 /*-************************************************************************************************************//**
1315 @interface XEventListener
1316 @short not implemented!
1317 @descr We are a status listener ... and so we must be an event listener too ... But we doesn't need it realy!
1318 We are a temp. listener only and our lifetime isn't smaller then of our temp. used dispatcher.
1320 @seealso method loadComponentFromURL()
1327 *//*-*************************************************************************************************************/
1328 void SAL_CALL
Desktop::disposing( const css::lang::EventObject
& ) throw( css::uno::RuntimeException
)
1330 LOG_ERROR( "Desktop::disposing()", "Algorithm error! Normaly desktop is temp. listener ... not all the time. So this method shouldn't be called." )
1333 /*-************************************************************************************************************//**
1334 @interface XInteractionHandler
1335 @short callback for loadComponentFromURL for detected exceptions during load proccess
1336 @descr In this case we must cancel loading and throw these detected exception again as result
1337 of our own called method.
1340 Normal loop in loadComponentFromURL() breaks on setted member m_eLoadState during callback statusChanged().
1341 But these interaction feature implements second way to do so! So we must look on different callbacks
1342 for same operation ... and live with it.
1344 Search for given continuations too. If any XInteractionAbort exist ... use it to abort further operations
1345 for currently running operation!
1347 @seealso method loadComponentFromURL()
1348 @seealso member m_eLoadState
1350 @param "xRequest", request for interaction - normal a wrapped target exception from bottom services
1355 *//*-*************************************************************************************************************/
1356 void SAL_CALL
Desktop::handle( const css::uno::Reference
< css::task::XInteractionRequest
>& xRequest
) throw( css::uno::RuntimeException
)
1358 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1359 // Register transaction and reject wrong calls.
1360 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1362 // Don't check incoming request!
1363 // If somewhere starts interaction without right parameter - he maked something wrong.
1364 // loadComponentFromURL() waits for thjese event - otherwise it yield for ever!
1366 // get packed request and work on it first
1367 // Attention: Don't set it on internal member BEFORE interaction is finished - because
1368 // "loadComponentFromURL()" yield tills this member is changed. If we do it before
1369 // interaction finish we can't guarantee right functionality. May be we cancel load process to erliear ...
1370 css::uno::Any aRequest
= xRequest
->getRequest();
1372 // extract continuations from request
1373 css::uno::Sequence
< css::uno::Reference
< css::task::XInteractionContinuation
> > lContinuations
= xRequest
->getContinuations();
1374 css::uno::Reference
< css::task::XInteractionAbort
> xAbort
;
1375 css::uno::Reference
< css::task::XInteractionApprove
> xApprove
;
1376 css::uno::Reference
< css::document::XInteractionFilterSelect
> xFilterSelect
;
1377 sal_Bool bAbort
= sal_False
;
1379 sal_Int32 nCount
=lContinuations
.getLength();
1380 for( sal_Int32 nStep
=0; nStep
<nCount
; ++nStep
)
1383 xAbort
= css::uno::Reference
< css::task::XInteractionAbort
>( lContinuations
[nStep
], css::uno::UNO_QUERY
);
1385 if( ! xApprove
.is() )
1386 xApprove
= css::uno::Reference
< css::task::XInteractionApprove
>( lContinuations
[nStep
], css::uno::UNO_QUERY
);
1388 if( ! xFilterSelect
.is() )
1389 xFilterSelect
= css::uno::Reference
< css::document::XInteractionFilterSelect
>( lContinuations
[nStep
], css::uno::UNO_QUERY
);
1392 // differ between abortable interactions (error, unknown filter ...)
1393 // and other ones (ambigous but not unknown filter ...)
1394 css::task::ErrorCodeRequest aErrorCodeRequest
;
1395 css::document::AmbigousFilterRequest aAmbigousFilterRequest
;
1396 if( aRequest
>>= aAmbigousFilterRequest
)
1398 if( xFilterSelect
.is() )
1400 xFilterSelect
->setFilter( aAmbigousFilterRequest
.SelectedFilter
); // user selected filter wins!
1401 xFilterSelect
->select();
1404 else if( aRequest
>>= aErrorCodeRequest
)
1406 sal_Bool bWarning
= ((aErrorCodeRequest
.ErrCode
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
);
1407 if (xApprove
.is() && bWarning
)
1416 else if( xAbort
.is() )
1422 /* SAFE AREA ------------------------------------------------------------------------------------------- */
1423 // Ok now it's time to break yield loop of loadComponentFromURL().
1424 // But only for realy aborted requests!
1425 // For example warnings will be approved and we wait for any success story ...
1428 WriteGuard
aWriteLock( m_aLock
);
1429 m_eLoadState
= E_INTERACTION
;
1430 m_aInteractionRequest
= aRequest
;
1431 aWriteLock
.unlock();
1433 /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
1436 //-----------------------------------------------------------------------------
1437 ::sal_Int32 SAL_CALL
Desktop::leaseNumber( const css::uno::Reference
< css::uno::XInterface
>& xComponent
)
1438 throw (css::lang::IllegalArgumentException
,
1439 css::uno::RuntimeException
)
1441 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1442 return m_xTitleNumberGenerator
->leaseNumber (xComponent
);
1445 //-----------------------------------------------------------------------------
1446 void SAL_CALL
Desktop::releaseNumber( ::sal_Int32 nNumber
)
1447 throw (css::lang::IllegalArgumentException
,
1448 css::uno::RuntimeException
)
1450 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1451 m_xTitleNumberGenerator
->releaseNumber (nNumber
);
1454 //-----------------------------------------------------------------------------
1455 void SAL_CALL
Desktop::releaseNumberForComponent( const css::uno::Reference
< css::uno::XInterface
>& xComponent
)
1456 throw (css::lang::IllegalArgumentException
,
1457 css::uno::RuntimeException
)
1459 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1460 m_xTitleNumberGenerator
->releaseNumberForComponent (xComponent
);
1463 //-----------------------------------------------------------------------------
1464 OUString SAL_CALL
Desktop::getUntitledPrefix()
1465 throw (css::uno::RuntimeException
)
1467 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1468 return m_xTitleNumberGenerator
->getUntitledPrefix ();
1471 /*-************************************************************************************************************//**
1472 @short try to convert a property value
1473 @descr This method is called from helperclass "OPropertySetHelper".
1474 Don't use this directly!
1475 You must try to convert the value of given DESKTOP_PROPHANDLE and
1476 return results of this operation. This will be used to ask vetoable
1477 listener. If no listener has a veto, we will change value realy!
1478 ( in method setFastPropertyValue_NoBroadcast(...) )
1480 @attention Methods of OPropertySethelper are safed by using our shared osl mutex! (see ctor!)
1481 So we must use different locks to make our implementation threadsafe.
1483 @seealso class OPropertySetHelper
1484 @seealso method setFastPropertyValue_NoBroadcast()
1486 @param "aConvertedValue" new converted value of property
1487 @param "aOldValue" old value of property
1488 @param "nHandle" handle of property
1489 @param "aValue" new value of property
1490 @return sal_True if value will be changed, sal_FALSE otherway
1492 @onerror IllegalArgumentException, if you call this with an invalid argument
1494 *//*-*************************************************************************************************************/
1495 sal_Bool SAL_CALL
Desktop::convertFastPropertyValue( css::uno::Any
& aConvertedValue
,
1496 css::uno::Any
& aOldValue
,
1498 const css::uno::Any
& aValue
) throw( css::lang::IllegalArgumentException
)
1500 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1501 // Register transaction and reject wrong calls.
1502 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1504 // Initialize state with sal_False !!!
1505 // (Handle can be invalid)
1506 sal_Bool bReturn
= sal_False
;
1510 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO
:
1511 bReturn
= PropHelper::willPropertyBeChanged(
1512 css::uno::makeAny(m_bSuspendQuickstartVeto
),
1517 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER
:
1518 bReturn
= PropHelper::willPropertyBeChanged(
1519 css::uno::makeAny(m_xDispatchRecorderSupplier
),
1524 case DESKTOP_PROPHANDLE_TITLE
:
1525 bReturn
= PropHelper::willPropertyBeChanged(
1526 css::uno::makeAny(m_sTitle
),
1533 // Return state of operation.
1537 /*-************************************************************************************************************//**
1538 @short set value of a transient property
1539 @descr This method is calling from helperclass "OPropertySetHelper".
1540 Don't use this directly!
1541 Handle and value are valid everyway! You must set the new value only.
1542 After this, baseclass send messages to all listener automaticly.
1544 @seealso class OPropertySetHelper
1546 @param "nHandle" handle of property to change
1547 @param "aValue" new value of property
1550 @onerror An exception is thrown.
1552 *//*-*************************************************************************************************************/
1553 void SAL_CALL
Desktop::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
,
1554 const css::uno::Any
& aValue
) throw( css::uno::Exception
)
1556 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1557 // Register transaction and reject wrong calls.
1558 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1562 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO
: aValue
>>= m_bSuspendQuickstartVeto
;
1564 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER
: aValue
>>= m_xDispatchRecorderSupplier
;
1566 case DESKTOP_PROPHANDLE_TITLE
: aValue
>>= m_sTitle
;
1571 /*-************************************************************************************************************//**
1572 @short get value of a transient property
1573 @descr This method is calling from helperclass "OPropertySetHelper".
1574 Don't use this directly!
1576 @attention We don't need any mutex or lock here ... We use threadsafe container or methods here only!
1578 @seealso class OPropertySetHelper
1580 @param "nHandle" handle of property to change
1581 @param "aValue" current value of property
1586 *//*-*************************************************************************************************************/
1587 void SAL_CALL
Desktop::getFastPropertyValue( css::uno::Any
& aValue
,
1588 sal_Int32 nHandle
) const
1590 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1591 // Register transaction and reject wrong calls.
1592 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1596 case DESKTOP_PROPHANDLE_ACTIVEFRAME
: aValue
<<= m_aChildTaskContainer
.getActive();
1598 case DESKTOP_PROPHANDLE_ISPLUGGED
: aValue
<<= sal_False
;
1600 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO
: aValue
<<= m_bSuspendQuickstartVeto
;
1602 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER
: aValue
<<= m_xDispatchRecorderSupplier
;
1604 case DESKTOP_PROPHANDLE_TITLE
: aValue
<<= m_sTitle
;
1609 /*-************************************************************************************************************//**
1610 @short return structure and information about transient properties
1611 @descr This method is calling from helperclass "OPropertySetHelper".
1612 Don't use this directly!
1614 @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
1615 Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
1616 So we could have two different mutex/lock mechanism at the same object.
1618 @seealso class OPropertySetHelper
1621 @return structure with property-information
1625 *//*-*************************************************************************************************************/
1626 ::cppu::IPropertyArrayHelper
& SAL_CALL
Desktop::getInfoHelper()
1628 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1629 // Register transaction and reject wrong calls.
1630 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1632 // Optimize this method !
1633 // We initialize a static variable only one time. And we don't must use a mutex at every call!
1634 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
1635 static ::cppu::OPropertyArrayHelper
* pInfoHelper
= NULL
;
1637 if( pInfoHelper
== NULL
)
1639 // Ready for multithreading
1640 ::osl::MutexGuard
aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
1641 // Control this pointer again, another instance can be faster then these!
1642 if( pInfoHelper
== NULL
)
1644 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
1645 // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
1646 // "sal_True" say: Table is sorted by name.
1647 static ::cppu::OPropertyArrayHelper
aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True
);
1648 pInfoHelper
= &aInfoHelper
;
1652 return(*pInfoHelper
);
1655 /*-************************************************************************************************************//**
1656 @short return propertysetinfo
1657 @descr You can call this method to get information about transient properties
1660 @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
1661 Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
1662 So we could have two different mutex/lock mechanism at the same object.
1664 @seealso class OPropertySetHelper
1665 @seealso interface XPropertySet
1666 @seealso interface XMultiPropertySet
1669 @return reference to object with information [XPropertySetInfo]
1673 *//*-*************************************************************************************************************/
1674 css::uno::Reference
< css::beans::XPropertySetInfo
> SAL_CALL
Desktop::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException
)
1676 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1677 // Register transaction and reject wrong calls.
1678 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1680 // Optimize this method !
1681 // We initialize a static variable only one time. And we don't must use a mutex at every call!
1682 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
1683 static css::uno::Reference
< css::beans::XPropertySetInfo
>* pInfo
= NULL
;
1687 // Ready for multithreading
1688 ::osl::MutexGuard
aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
1689 // Control this pointer again, another instance can be faster then these!
1692 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
1693 // (Use method "getInfoHelper()".)
1694 static css::uno::Reference
< css::beans::XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
1702 /*-************************************************************************************************************//**
1703 @short return current component of current frame
1704 @descr The desktop himself has no component. But every frame in subtree.
1705 If somewhere call getCurrentComponent() at this class, we try to find the right frame and
1706 then we try to become his component. It can be a VCL-component, the model or the controller
1709 @attention We don't work on internal member ... so we doesn't need any lock here.
1711 @seealso method getCurrentComponent();
1713 @param "xFrame", reference to valid frame in hierarchy. Method is not defined for invalid values.
1714 But we don't check these. Its an IMPL-method and caller must use it right!
1715 @return A reference to found component.
1717 @onerror A null reference is returned.
1719 *//*-*************************************************************************************************************/
1720 css::uno::Reference
< css::lang::XComponent
> Desktop::impl_getFrameComponent( const css::uno::Reference
< css::frame::XFrame
>& xFrame
) const
1722 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1723 // Register transaction and reject wrong calls.
1724 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1726 // Set default return value, if method failed.
1727 css::uno::Reference
< css::lang::XComponent
> xComponent
;
1728 // Does no controller exists?
1729 css::uno::Reference
< css::frame::XController
> xController
= xFrame
->getController();
1730 if( xController
.is() == sal_False
)
1732 // Controller not exist - use the VCL-component.
1733 xComponent
= css::uno::Reference
< css::lang::XComponent
>( xFrame
->getComponentWindow(), css::uno::UNO_QUERY
);
1737 // Does no model exists?
1738 css::uno::Reference
< css::frame::XModel
> xModel( xController
->getModel(), css::uno::UNO_QUERY
);
1739 if( xModel
.is() == sal_True
)
1741 // Model exist - use the model as component.
1742 xComponent
= css::uno::Reference
< css::lang::XComponent
>( xModel
, css::uno::UNO_QUERY
);
1746 // Model not exist - use the controller as component.
1747 xComponent
= css::uno::Reference
< css::lang::XComponent
>( xController
, css::uno::UNO_QUERY
);
1754 /*-************************************************************************************************************//**
1755 @short create table with information about properties
1756 @descr We use a helper class to support properties. These class need some information about this.
1757 These method create a new static description table with name, type, r/w-flags and so on ...
1759 @seealso class OPropertySetHelper
1760 @seealso method getInfoHelper()
1763 @return Static table with information about properties.
1767 *//*-*************************************************************************************************************/
1768 const css::uno::Sequence
< css::beans::Property
> Desktop::impl_getStaticPropertyDescriptor()
1770 // Create a property array to initialize sequence!
1771 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
1772 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
1773 // It's necessary for methods of OPropertySetHelper.
1775 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
1777 const css::beans::Property pProperties
[] =
1779 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
),
1780 css::beans::Property( DESKTOP_PROPNAME_DISPATCHRECORDERSUPPLIER
, DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER
, ::getCppuType((const css::uno::Reference
< css::frame::XDispatchRecorderSupplier
>*)NULL
), css::beans::PropertyAttribute::TRANSIENT
),
1781 css::beans::Property( DESKTOP_PROPNAME_ISPLUGGED
, DESKTOP_PROPHANDLE_ISPLUGGED
, ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT
| css::beans::PropertyAttribute::READONLY
),
1782 css::beans::Property( DESKTOP_PROPNAME_SUSPENDQUICKSTARTVETO
, DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO
, ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT
),
1783 css::beans::Property( DESKTOP_PROPNAME_TITLE
, DESKTOP_PROPHANDLE_TITLE
, ::getCppuType((const OUString
*)NULL
) , css::beans::PropertyAttribute::TRANSIENT
),
1785 // Use it to initialize sequence!
1786 const css::uno::Sequence
< css::beans::Property
> lPropertyDescriptor( pProperties
, DESKTOP_PROPCOUNT
);
1787 // Return "PropertyDescriptor"
1788 return lPropertyDescriptor
;
1791 //=============================================================================
1792 void Desktop::impl_sendQueryTerminationEvent(Desktop::TTerminateListenerList
& lCalledListener
,
1797 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1799 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aListenerContainer
.getContainer( ::getCppuType( ( const css::uno::Reference
< css::frame::XTerminateListener
>*) NULL
) );
1803 css::lang::EventObject
aEvent( static_cast< ::cppu::OWeakObject
* >(this) );
1805 ::cppu::OInterfaceIteratorHelper
aIterator( *pContainer
);
1806 while ( aIterator
.hasMoreElements() )
1810 css::uno::Reference
< css::frame::XTerminateListener
> xListener(aIterator
.next(), css::uno::UNO_QUERY
);
1811 if ( ! xListener
.is() )
1813 xListener
->queryTermination( aEvent
);
1814 lCalledListener
.push_back(xListener
);
1816 catch( const css::frame::TerminationVetoException
& )
1818 // first veto will stop notification loop.
1822 catch( const css::uno::Exception
& )
1824 // clean up container.
1825 // E.g. dead remote listener objects can make trouble otherwise.
1826 // Iterator implementation allows removing objects during it's used !
1832 //=============================================================================
1833 void Desktop::impl_sendCancelTerminationEvent(const Desktop::TTerminateListenerList
& lCalledListener
)
1835 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1837 css::lang::EventObject
aEvent( static_cast< ::cppu::OWeakObject
* >(this) );
1838 Desktop::TTerminateListenerList::const_iterator pIt
;
1839 for ( pIt
= lCalledListener
.begin();
1840 pIt
!= lCalledListener
.end ();
1845 // Note: cancelTermination() is a new and optional interface method !
1846 css::uno::Reference
< css::frame::XTerminateListener
> xListener
= *pIt
;
1847 css::uno::Reference
< css::frame::XTerminateListener2
> xListenerGeneration2(xListener
, css::uno::UNO_QUERY
);
1848 if ( ! xListenerGeneration2
.is() )
1850 xListenerGeneration2
->cancelTermination( aEvent
);
1852 catch( const css::uno::Exception
& )
1857 //=============================================================================
1858 void Desktop::impl_sendNotifyTerminationEvent()
1860 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1862 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aListenerContainer
.getContainer( ::getCppuType( ( const css::uno::Reference
< css::frame::XTerminateListener
>*) NULL
) );
1866 css::lang::EventObject
aEvent( static_cast< ::cppu::OWeakObject
* >(this) );
1868 ::cppu::OInterfaceIteratorHelper
aIterator( *pContainer
);
1869 while ( aIterator
.hasMoreElements() )
1873 css::uno::Reference
< css::frame::XTerminateListener
> xListener(aIterator
.next(), css::uno::UNO_QUERY
);
1874 if ( ! xListener
.is() )
1876 xListener
->notifyTermination( aEvent
);
1878 catch( const css::uno::Exception
& )
1880 // clean up container.
1881 // E.g. dead remote listener objects can make trouble otherwise.
1882 // Iterator implementation allows removing objects during it's used !
1888 //=============================================================================
1889 ::sal_Bool
Desktop::impl_closeFrames(::sal_Bool bAllowUI
)
1891 ReadGuard
aReadLock( m_aLock
); // start synchronize
1892 css::uno::Sequence
< css::uno::Reference
< css::frame::XFrame
> > lFrames
= m_aChildTaskContainer
.getAllElements();
1893 aReadLock
.unlock(); // end synchronize
1895 ::sal_Int32 c
= lFrames
.getLength();
1897 ::sal_Int32 nNonClosedFrames
= 0;
1899 for( i
=0; i
<c
; ++i
)
1903 css::uno::Reference
< css::frame::XFrame
> xFrame
= lFrames
[i
];
1905 // XController.suspend() will show an UI ...
1906 // Use it in case it was allowed from outside only.
1907 sal_Bool bSuspended
= sal_False
;
1908 css::uno::Reference
< css::frame::XController
> xController( xFrame
->getController(), css::uno::UNO_QUERY
);
1911 ( xController
.is() )
1914 bSuspended
= xController
->suspend( sal_True
);
1922 // Try to close frame (in case no UI was allowed without calling XController->suspend() before!)
1923 // But don't deliver ownership to any other one!
1924 // This method can be called again.
1925 css::uno::Reference
< css::util::XCloseable
> xClose( xFrame
, css::uno::UNO_QUERY
);
1930 xClose
->close(sal_False
);
1932 catch(const css::util::CloseVetoException
&)
1934 // Any internal process of this frame disagree with our request.
1935 // Safe this state but dont break these loop. Other frames has to be closed!
1938 // Reactivate controller.
1939 // It can happen that XController.suspend() returned true ... but a registered close listener
1940 // throwed these veto exception. Then the controller has to be reactivated. Otherwise
1941 // these document doesnt work any more.
1946 xController
->suspend(sal_False
);
1949 // If interface XClosable interface exists and was used ...
1950 // it's not allowed to use XComponent->dispose() also !
1954 // XClosable not supported ?
1955 // Then we have to dispose these frame hardly.
1956 css::uno::Reference
< css::lang::XComponent
> xDispose( xFrame
, css::uno::UNO_QUERY
);
1957 if ( xDispose
.is() )
1958 xDispose
->dispose();
1960 // Don't remove these frame from our child container!
1961 // A frame do it by itself inside close()/dispose() method.
1963 catch(const css::lang::DisposedException
&)
1965 // Dispose frames are closed frames.
1966 // So we can count it here .-)
1970 return (nNonClosedFrames
< 1);
1973 //_________________________________________________________________________________________________________________
1975 //_________________________________________________________________________________________________________________
1977 /*-----------------------------------------------------------------------------------------------------------------
1978 The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
1979 we return "sal_True". (otherwise sal_False) This mechanism is used to throw an ASSERT!
1980 -----------------------------------------------------------------------------------------------------------------*/
1982 #ifdef ENABLE_ASSERTIONS
1984 //*****************************************************************************************************************
1985 // We work with valid servicemanager only.
1986 sal_Bool
Desktop::implcp_ctor( const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xFactory
)
1989 ( &xFactory
== NULL
) ||
1990 ( xFactory
.is() == sal_False
)
1994 //*****************************************************************************************************************
1995 // We work with valid listener only.
1996 sal_Bool
Desktop::implcp_addEventListener( const css::uno::Reference
< css::lang::XEventListener
>& xListener
)
1999 ( &xListener
== NULL
) ||
2000 ( xListener
.is() == sal_False
)
2004 //*****************************************************************************************************************
2005 // We work with valid listener only.
2006 sal_Bool
Desktop::implcp_removeEventListener( const css::uno::Reference
< css::lang::XEventListener
>& xListener
)
2009 ( &xListener
== NULL
) ||
2010 ( xListener
.is() == sal_False
)
2014 #endif // #ifdef ENABLE_ASSERTIONS
2016 } // namespace framework
2018 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */