1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: desktop.cxx,v $
10 * $Revision: 1.64.80.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 //_________________________________________________________________________________________________________________
36 //_________________________________________________________________________________________________________________
37 #include <loadenv/loadenv.hxx>
39 #ifndef __FRAMEWORK_LOADENV_TARGETHELPER_HXX_
40 #include <loadenv/targethelper.hxx>
43 #ifndef __FRAMEWORK_DESKTOP_HXX_
44 #include <services/desktop.hxx>
46 #include <helper/ocomponentaccess.hxx>
47 #include <dispatch/dispatchprovider.hxx>
49 #ifndef __FRAMEWORK_DISPATCH_INTERCEPTIONHELPER_HXX_
50 #include <dispatch/interceptionhelper.hxx>
52 #include <classes/taskcreator.hxx>
53 #include <threadhelp/transactionguard.hxx>
54 #include <threadhelp/writeguard.hxx>
55 #include <threadhelp/readguard.hxx>
58 #include <properties.h>
60 #include <classes/resource.hrc>
61 #include <classes/fwkresid.hxx>
63 //_________________________________________________________________________________________________________________
65 //_________________________________________________________________________________________________________________
66 #include <com/sun/star/beans/PropertyAttribute.hpp>
67 #include <com/sun/star/frame/FrameSearchFlag.hpp>
68 #include <com/sun/star/awt/XToolkit.hpp>
69 #include <com/sun/star/awt/XWindow.hpp>
70 #include <com/sun/star/awt/XWindowPeer.hpp>
71 #include <com/sun/star/awt/WindowDescriptor.hpp>
72 #include <com/sun/star/awt/WindowAttribute.hpp>
73 #include <com/sun/star/awt/PosSize.hpp>
74 #include <com/sun/star/util/XURLTransformer.hpp>
75 #include <com/sun/star/task/XInteractionAbort.hpp>
76 #include <com/sun/star/task/XInteractionApprove.hpp>
77 #include <com/sun/star/document/XInteractionFilterSelect.hpp>
78 #include <com/sun/star/document/AmbigousFilterRequest.hpp>
79 #include <com/sun/star/task/ErrorCodeRequest.hpp>
80 #include <com/sun/star/ucb/InteractiveIOException.hpp>
81 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
82 #include <com/sun/star/frame/XNotifyingDispatch.hpp>
83 #include <com/sun/star/frame/DispatchResultState.hpp>
84 #include <com/sun/star/lang/IllegalArgumentException.hpp>
85 #include <com/sun/star/util/XCloseable.hpp>
86 #include <com/sun/star/document/MacroExecMode.hpp>
87 #include <com/sun/star/document/UpdateDocMode.hpp>
88 #include <com/sun/star/frame/XTerminateListener2.hpp>
90 //_________________________________________________________________________________________________________________
91 // includes of other projects
92 //_________________________________________________________________________________________________________________
93 #include <cppuhelper/queryinterface.hxx>
94 #include <cppuhelper/typeprovider.hxx>
95 #include <cppuhelper/factory.hxx>
96 #include <cppuhelper/proptypehlp.hxx>
97 #include <rtl/ustrbuf.hxx>
98 #include <rtl/logfile.hxx>
99 #include <vcl/svapp.hxx>
102 #include <tools/errinf.hxx>
104 #include <comphelper/extract.hxx>
106 //_________________________________________________________________________________________________________________
108 //_________________________________________________________________________________________________________________
112 //_________________________________________________________________________________________________________________
113 // non exported const
114 //_________________________________________________________________________________________________________________
116 //_________________________________________________________________________________________________________________
117 // non exported definitions
118 //_________________________________________________________________________________________________________________
120 //_________________________________________________________________________________________________________________
122 //_________________________________________________________________________________________________________________
124 //*****************************************************************************************************************
125 // XInterface, XTypeProvider, XServiceInfo
126 //*****************************************************************************************************************
127 DEFINE_XINTERFACE_15 ( Desktop
,
129 DIRECT_INTERFACE( css::lang::XTypeProvider
),
130 DIRECT_INTERFACE( css::lang::XServiceInfo
),
131 DIRECT_INTERFACE( css::frame::XDesktop
),
132 DIRECT_INTERFACE( css::frame::XComponentLoader
),
133 DIRECT_INTERFACE( css::frame::XTasksSupplier
),
134 DIRECT_INTERFACE( css::frame::XDispatchProvider
),
135 DIRECT_INTERFACE( css::frame::XDispatchProviderInterception
),
136 DIRECT_INTERFACE( css::frame::XFramesSupplier
),
137 DIRECT_INTERFACE( css::frame::XFrame
),
138 DIRECT_INTERFACE( css::lang::XComponent
),
139 DIRECT_INTERFACE( css::frame::XDispatchResultListener
),
140 DIRECT_INTERFACE( css::lang::XEventListener
),
141 DIRECT_INTERFACE( css::task::XInteractionHandler
),
142 DIRECT_INTERFACE( css::beans::XPropertySet
),
143 DIRECT_INTERFACE( css::frame::XUntitledNumbers
)
146 DEFINE_XTYPEPROVIDER_15 ( Desktop
,
147 css::lang::XTypeProvider
,
148 css::lang::XServiceInfo
,
149 css::frame::XDesktop
,
150 css::frame::XComponentLoader
,
151 css::frame::XTasksSupplier
,
152 css::frame::XDispatchProvider
,
153 css::frame::XDispatchProviderInterception
,
154 css::frame::XFramesSupplier
,
156 css::lang::XComponent
,
157 css::frame::XDispatchResultListener
,
158 css::lang::XEventListener
,
159 css::task::XInteractionHandler
,
160 css::beans::XPropertySet
,
161 css::frame::XUntitledNumbers
164 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( Desktop
,
165 ::cppu::OWeakObject
,
166 SERVICENAME_DESKTOP
,
167 IMPLEMENTATIONNAME_DESKTOP
170 DEFINE_INIT_SERVICE ( Desktop
,
173 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
174 to create a new instance of this class by our own supported service factory.
175 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
178 //-------------------------------------------------------------------------------------------------------------
179 // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
180 // We hold member as reference ... not as pointer too!
181 // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
182 // But look on dispose() for right order of deinitialization.
183 OFrames
* pFramesHelper
= new OFrames( m_xFactory
, this, &m_aChildTaskContainer
);
184 m_xFramesHelper
= css::uno::Reference
< css::frame::XFrames
>( static_cast< ::cppu::OWeakObject
* >(pFramesHelper
), css::uno::UNO_QUERY
);
186 //-------------------------------------------------------------------------------------------------------------
187 // Initialize a new dispatchhelper-object to handle dispatches.
188 // We use these helper as slave for our interceptor helper ... not directly!
189 // But he is event listener on THIS instance!
190 DispatchProvider
* pDispatchHelper
= new DispatchProvider( m_xFactory
, this );
191 css::uno::Reference
< css::frame::XDispatchProvider
> xDispatchProvider( static_cast< ::cppu::OWeakObject
* >(pDispatchHelper
), css::uno::UNO_QUERY
);
193 //-------------------------------------------------------------------------------------------------------------
194 // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
195 // Set created dispatch provider as slowest slave of it.
196 // Hold interception helper by reference only - not by pointer!
197 // So it's easiear to destroy it.
198 InterceptionHelper
* pInterceptionHelper
= new InterceptionHelper( this, xDispatchProvider
);
199 m_xDispatchHelper
= css::uno::Reference
< css::frame::XDispatchProvider
>( static_cast< ::cppu::OWeakObject
* >(pInterceptionHelper
), css::uno::UNO_QUERY
);
201 ::rtl::OUStringBuffer
sUntitledPrefix (256);
202 sUntitledPrefix
.append (::rtl::OUString( String( FwkResId( STR_UNTITLED_DOCUMENT
))));
203 sUntitledPrefix
.appendAscii (" ");
205 ::comphelper::NumberedCollection
* pNumbers
= new ::comphelper::NumberedCollection ();
206 m_xTitleNumberGenerator
= css::uno::Reference
< css::frame::XUntitledNumbers
>(static_cast< ::cppu::OWeakObject
* >(pNumbers
), css::uno::UNO_QUERY_THROW
);
207 pNumbers
->setOwner ( static_cast< ::cppu::OWeakObject
* >(this) );
208 pNumbers
->setUntitledPrefix ( sUntitledPrefix
.makeStringAndClear () );
210 // Safe impossible cases
211 // We can't work without this helper!
212 LOG_ASSERT2( m_xFramesHelper
.is ()==sal_False
, "Desktop::Desktop()", "Frames helper is not valid. XFrames, XIndexAccess and XElementAcces are not supported!\n")
213 LOG_ASSERT2( m_xDispatchHelper
.is()==sal_False
, "Desktop::Desktop()", "Dispatch helper is not valid. XDispatch will not work correctly!\n" )
215 // Enable object for real working!
216 // Otherwise all calls will be rejected ...
217 m_aTransactionManager
.setWorkingMode( E_WORK
);
221 /*-************************************************************************************************************//**
222 @short standard constructor to create instance by factory
223 @descr This constructor initialize a new instance of this class by valid factory,
224 and will be set valid values on his member and baseclasses.
226 @attention a) Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
227 will get over this. (e.g. using of your reference as parameter to initialize some member)
228 Do such things in DEFINE_INIT_SERVICE() method, which is called automaticly after your ctor!!!
229 b) Baseclass OBroadcastHelper is a typedef in namespace cppu!
230 The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
231 If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
232 I don't know why! (other compiler not tested .. but it works!)
234 @seealso method DEFINE_INIT_SERVICE()
236 @param "xFactory" is the multi service manager, which create this instance.
237 The value must be different from NULL!
240 @onerror We throw an ASSERT in debug version or do nothing in relaese version.
241 *//*-*************************************************************************************************************/
242 Desktop::Desktop( const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xFactory
)
243 // Init baseclasses first
244 // Attention: Don't change order of initialization!
245 // ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
246 // We must garant right initialization and a valid value of this to initialize other baseclasses!
247 : ThreadHelpBase ( &Application::GetSolarMutex() )
248 , TransactionBase ( )
249 , ::cppu::OBroadcastHelperVar
< ::cppu::OMultiTypeInterfaceContainerHelper
, ::cppu::OMultiTypeInterfaceContainerHelper::keyType
> ( m_aLock
.getShareableOslMutex() )
250 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper
* >(this)) )
251 , ::cppu::OWeakObject ( )
253 #ifdef ENABLE_ASSERTIONS
254 , m_bIsTerminated ( sal_False
) // see dispose() for further informations!
256 , m_xFactory ( xFactory
)
257 , m_aChildTaskContainer ( )
258 , m_aListenerContainer ( m_aLock
.getShareableOslMutex() )
259 , m_xFramesHelper ( )
260 , m_xDispatchHelper ( )
261 , m_eLoadState ( E_NOTSET
)
263 , m_aInteractionRequest ( )
264 , m_bSuspendQuickstartVeto( sal_False
)
265 , m_aCommandOptions ( )
268 , m_xDispatchRecorderSupplier( )
269 , m_xPipeTerminator ( )
270 , m_xQuickLauncher ( )
271 , m_xSWThreadManager ( )
272 , m_xSfxTerminator ( )
273 , m_xTitleNumberGenerator ( )
275 // Safe impossible cases
276 // We don't accept all incoming parameter.
277 LOG_ASSERT2( implcp_ctor( xFactory
), "Desktop::Desktop()", "Invalid parameter detected!")
280 /*-************************************************************************************************************//**
281 @short standard destructor
282 @descr This one do NOTHING! Use dispose() instaed of this.
284 @seealso method dispose()
290 *//*-*************************************************************************************************************/
293 LOG_ASSERT2( m_bIsTerminated
==sal_False
, "Desktop::~Desktop()", "Who forgot to terminate the desktop service?" )
294 LOG_ASSERT2( m_aTransactionManager
.getWorkingMode()!=E_CLOSE
, "Desktop::~Desktop()", "Who forgot to dispose this service?" )
297 //=============================================================================
298 sal_Bool SAL_CALL
Desktop::terminate()
299 throw( css::uno::RuntimeException
)
301 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
304 ReadGuard
aReadLock( m_aLock
);
306 css::uno::Reference
< css::frame::XTerminateListener
> xPipeTerminator
= m_xPipeTerminator
;
307 css::uno::Reference
< css::frame::XTerminateListener
> xQuickLauncher
= m_xQuickLauncher
;
308 css::uno::Reference
< css::frame::XTerminateListener
> xSWThreadManager
= m_xSWThreadManager
;
309 css::uno::Reference
< css::frame::XTerminateListener
> xSfxTerminator
= m_xSfxTerminator
;
311 css::lang::EventObject
aEvent ( static_cast< ::cppu::OWeakObject
* >(this) );
312 ::sal_Bool bAskQuickStart
= !m_bSuspendQuickstartVeto
;
317 //-------------------------------------------------------------------------------------------------------------
318 // Ask normal terminate listener. They could stop terminate without closing any open document.
319 Desktop::TTerminateListenerList lCalledTerminationListener
;
320 ::sal_Bool bVeto
= sal_False
;
321 impl_sendQueryTerminationEvent(lCalledTerminationListener
, bVeto
);
324 impl_sendCancelTerminationEvent(lCalledTerminationListener
);
328 //-------------------------------------------------------------------------------------------------------------
329 // try to close all open frames.
330 // Allow using of any UI ... because Desktop.terminate() was designed as UI functionality in the past.
331 ::sal_Bool bAllowUI
= sal_True
;
332 ::sal_Bool bFramesClosed
= impl_closeFrames(bAllowUI
);
333 if ( ! bFramesClosed
)
335 impl_sendCancelTerminationEvent(lCalledTerminationListener
);
339 //-------------------------------------------------------------------------------------------------------------
340 // Normal listener had no problem ...
341 // all frames was closed ...
342 // now it's time to ask our specialized listener.
343 // They are handled these way because they wish to hinder the office on termination
344 // but they wish also closing of all frames.
347 // We shouldn't ask quicklauncher in case it was allowed from outside only.
348 // This is special trick to "ignore existing quick starter" for debug purposes.
351 // Order of alled listener is important !
352 // some of them are harmless .-)
353 // But some of them can be dangerous. E.g. it would be dangerous if we close our pipe
354 // and dont terminate in real because another listener throws a veto exception .-)
356 ::sal_Bool bTerminate
= sal_False
;
360 ( bAskQuickStart
) &&
361 ( xQuickLauncher
.is() )
364 xQuickLauncher
->queryTermination( aEvent
);
365 lCalledTerminationListener
.push_back( xQuickLauncher
);
368 if ( xSWThreadManager
.is() )
370 xSWThreadManager
->queryTermination( aEvent
);
371 lCalledTerminationListener
.push_back( xSWThreadManager
);
374 if ( xPipeTerminator
.is() )
376 xPipeTerminator
->queryTermination( aEvent
);
377 lCalledTerminationListener
.push_back( xPipeTerminator
);
380 if ( xSfxTerminator
.is() )
382 xSfxTerminator
->queryTermination( aEvent
);
383 lCalledTerminationListener
.push_back( xSfxTerminator
);
386 bTerminate
= sal_True
;
388 catch(const css::frame::TerminationVetoException
&)
390 bTerminate
= sal_False
;
394 impl_sendCancelTerminationEvent(lCalledTerminationListener
);
397 #ifdef ENABLE_ASSERTIONS
398 // "Protect" us against dispose before terminate calls!
399 // see dispose() for further informations.
400 /* SAFE AREA --------------------------------------------------------------------------------------- */
401 WriteGuard
aWriteLock( m_aLock
);
402 m_bIsTerminated
= sal_True
;
404 /* UNSAFE AREA ------------------------------------------------------------------------------------- */
407 impl_sendNotifyTerminationEvent();
410 ( bAskQuickStart
) &&
411 ( xQuickLauncher
.is() )
414 xQuickLauncher
->notifyTermination( aEvent
);
417 if ( xSWThreadManager
.is() )
418 xSWThreadManager
->notifyTermination( aEvent
);
420 if ( xPipeTerminator
.is() )
421 xPipeTerminator
->notifyTermination( aEvent
);
423 // Must be realy the last listener to be called.
424 // Because it shutdown the whole process asynchronous !
425 if ( xSfxTerminator
.is() )
426 xSfxTerminator
->notifyTermination( aEvent
);
433 //=============================================================================
434 void SAL_CALL
Desktop::addTerminateListener( const css::uno::Reference
< css::frame::XTerminateListener
>& xListener
)
435 throw( css::uno::RuntimeException
)
437 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
439 css::uno::Reference
< css::lang::XServiceInfo
> xInfo( xListener
, css::uno::UNO_QUERY
);
442 ::rtl::OUString sImplementationName
= xInfo
->getImplementationName();
445 WriteGuard
aWriteLock( m_aLock
);
447 if( sImplementationName
.equals(IMPLEMENTATIONNAME_SFXTERMINATOR
) )
449 m_xSfxTerminator
= xListener
;
452 if( sImplementationName
.equals(IMPLEMENTATIONNAME_PIPETERMINATOR
) )
454 m_xPipeTerminator
= xListener
;
457 if( sImplementationName
.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER
) )
459 m_xQuickLauncher
= xListener
;
462 if( sImplementationName
.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER
) )
464 m_xSWThreadManager
= xListener
;
472 // No lock required ... container is threadsafe by itself.
473 m_aListenerContainer
.addInterface( ::getCppuType( ( const css::uno::Reference
< css::frame::XTerminateListener
>*) NULL
), xListener
);
476 //=============================================================================
477 void SAL_CALL
Desktop::removeTerminateListener( const css::uno::Reference
< css::frame::XTerminateListener
>& xListener
)
478 throw( css::uno::RuntimeException
)
480 TransactionGuard
aTransaction( m_aTransactionManager
, E_SOFTEXCEPTIONS
);
482 css::uno::Reference
< css::lang::XServiceInfo
> xInfo( xListener
, css::uno::UNO_QUERY
);
485 ::rtl::OUString sImplementationName
= xInfo
->getImplementationName();
488 WriteGuard
aWriteLock( m_aLock
);
490 if( sImplementationName
.equals(IMPLEMENTATIONNAME_SFXTERMINATOR
) )
492 m_xSfxTerminator
.clear();
496 if( sImplementationName
.equals(IMPLEMENTATIONNAME_PIPETERMINATOR
) )
498 m_xPipeTerminator
.clear();
502 if( sImplementationName
.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER
) )
504 m_xQuickLauncher
.clear();
508 if( sImplementationName
.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER
) )
510 m_xSWThreadManager
.clear();
518 // No lock required ... container is threadsafe by itself.
519 m_aListenerContainer
.removeInterface( ::getCppuType( ( const css::uno::Reference
< css::frame::XTerminateListener
>*) NULL
), xListener
);
522 /*-************************************************************************************************************//**
524 @short get access to create enumerations of all current components
525 @descr You will be the owner of the returned object and must delete it if you don't use it again.
527 @seealso class TasksAccess
528 @seealso class TasksEnumeration
531 @return A reference to an XEnumerationAccess-object.
533 @onerror We return a null-reference.
535 *//*-*************************************************************************************************************/
536 css::uno::Reference
< css::container::XEnumerationAccess
> SAL_CALL
Desktop::getComponents() throw( css::uno::RuntimeException
)
538 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
539 // Register transaction and reject wrong calls.
540 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
542 // We use a helper class OComponentAccess to have access on all child components.
543 // Create it on demand and return it as a reference.
544 OComponentAccess
* pAccess
= new OComponentAccess( this );
545 css::uno::Reference
< css::container::XEnumerationAccess
> xAccess( static_cast< ::cppu::OWeakObject
* >(pAccess
), css::uno::UNO_QUERY
);
549 /*-************************************************************************************************************//**
551 @short return the current active component
552 @descr The most current component is the window, model or the controller of the current active frame.
554 @seealso method getCurrentFrame()
555 @seealso method impl_getFrameComponent()
558 @return A reference to the component.
560 @onerror We return a null-reference.
562 *//*-*************************************************************************************************************/
563 css::uno::Reference
< css::lang::XComponent
> SAL_CALL
Desktop::getCurrentComponent() throw( css::uno::RuntimeException
)
565 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
566 // Register transaction and reject wrong calls.
567 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
569 // Set return value if method failed.
570 css::uno::Reference
< css::lang::XComponent
> xComponent
;
572 // Get reference to current frame ...
573 // ... get component of this frame ... (It can be the window, the model or the controller.)
574 // ... and return the result.
575 css::uno::Reference
< css::frame::XFrame
> xCurrentFrame
= getCurrentFrame();
576 if( xCurrentFrame
.is() == sal_True
)
578 xComponent
= impl_getFrameComponent( xCurrentFrame
);
583 /*-************************************************************************************************************//**
585 @short return the current active frame in hierarchy
586 @descr There can be more then one different active pathes in our frame hierarchy. But only one of them
587 could be the most active frame (normal he has the focus).
588 Don't mix it with getActiveFrame()! That will return our current active frame, which must be
589 a direct child of us and should be a part(!) of an active path.
591 @seealso method getActiveFrame()
594 @return A valid reference, if there is an active frame.
595 A null reference , otherwise.
597 @onerror We return a null reference.
599 *//*-*************************************************************************************************************/
600 css::uno::Reference
< css::frame::XFrame
> SAL_CALL
Desktop::getCurrentFrame() throw( css::uno::RuntimeException
)
602 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
603 // Register transaction and reject wrong calls.
604 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
606 // Start search with ouer direct active frame (if it exist!).
607 // Search on his children for other active frames too.
608 // Stop if no one could be found and return last of found ones.
609 css::uno::Reference
< css::frame::XFramesSupplier
> xLast
= css::uno::Reference
< css::frame::XFramesSupplier
>( getActiveFrame(), css::uno::UNO_QUERY
);
610 if( xLast
.is() == sal_True
)
612 css::uno::Reference
< css::frame::XFramesSupplier
> xNext
= css::uno::Reference
< css::frame::XFramesSupplier
>( xLast
->getActiveFrame(), css::uno::UNO_QUERY
);
613 while( xNext
.is() == sal_True
)
616 xNext
= css::uno::Reference
< css::frame::XFramesSupplier
>( xNext
->getActiveFrame(), css::uno::UNO_QUERY
);
619 return css::uno::Reference
< css::frame::XFrame
>( xLast
, css::uno::UNO_QUERY
);
622 /*-************************************************************************************************************//**
623 @interface XComponentLoader
624 @short try to load given URL into a task
625 @descr You can give us some informations about the content, which you will load into a frame.
626 We search or create this target for you, make a type detection of given URL and try to load it.
627 As result of this operation we return the new created component or nothing, if loading failed.
631 @param "sURL" , URL, which represant the content
632 @param "sTargetFrameName" , name of target frame or special value like "_self", "_blank" ...
633 @param "nSearchFlags" , optional arguments for frame search, if target isn't a special one
634 @param "lArguments" , optional arguments for loading
635 @return A valid component reference, if loading was successfully.
636 A null reference otherwise.
638 @onerror We return a null reference.
640 *//*-*************************************************************************************************************/
641 css::uno::Reference
< css::lang::XComponent
> SAL_CALL
Desktop::loadComponentFromURL( const ::rtl::OUString
& sURL
,
642 const ::rtl::OUString
& sTargetFrameName
,
643 sal_Int32 nSearchFlags
,
644 const css::uno::Sequence
< css::beans::PropertyValue
>& lArguments
) throw( css::io::IOException
,
645 css::lang::IllegalArgumentException
,
646 css::uno::RuntimeException
)
648 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
649 // Register transaction and reject wrong calls.
650 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
651 RTL_LOGFILE_CONTEXT( aLog
, "framework (as96863) ::Desktop::loadComponentFromURL" );
653 ReadGuard
aReadLock(m_aLock
);
654 css::uno::Reference
< css::frame::XComponentLoader
> xThis(static_cast< css::frame::XComponentLoader
* >(this), css::uno::UNO_QUERY
);
655 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xFactory
;
658 RTL_LOGFILE_PRODUCT_CONTEXT( aLog2
, "PERFORMANCE - Desktop::loadComponentFromURL()" );
659 return LoadEnv::loadComponentFromURL(xThis
, xSMGR
, sURL
, sTargetFrameName
, nSearchFlags
, lArguments
);
662 /*-************************************************************************************************************//**
663 @interface XTasksSupplier
664 @short get access to create enumerations of ouer taskchilds
665 @descr Direct childs of desktop are tasks everytime.
666 Call these method to could create enumerations of it.
668 But; Don't forget - you will be the owner of returned object and must release it!
669 We use a helper class to implement the access interface. They hold a weakreference to us.
670 It can be, that the desktop is dead - but not your tasksaccess-object! Then they will do nothing!
671 You can't create enumerations then.
673 @attention Normaly we don't need any lock here. We don't work on internal member!
675 @seealso class TasksAccess
678 @return A reference to an accessobject, which can create enumerations of ouer childtasks.
680 @onerror A null reference is returned.
682 *//*-*************************************************************************************************************/
683 css::uno::Reference
< css::container::XEnumerationAccess
> SAL_CALL
Desktop::getTasks() throw( css::uno::RuntimeException
)
685 LOG_WARNING("Desktop::getTasks()", "Use of obsolete interface XTaskSupplier")
688 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
690 OTasksAccess* pTasksAccess = new OTasksAccess( this, &m_aChildTaskContainer );
691 css::uno::Reference< css::container::XEnumerationAccess > xAccess( static_cast< ::cppu::OWeakObject* >(pTasksAccess), css::uno::UNO_QUERY );
696 /*-************************************************************************************************************//**
697 @interface XTasksSupplier
698 @short return current active task of ouer direct childs
699 @descr Desktop childs are tasks only ! If we have an active path from desktop
700 as top to any frame on bottom, we must have an active direct child. His reference is returned here.
702 @attention a) Do not confuse it with getCurrentFrame()! The current frame don't must one of ouer direct childs.
703 It can be every frame in subtree and must have the focus (Is the last one of an active path!).
704 b) We don't need any lock here. Our container is threadsafe himself and live, if we live!
706 @seealso method getCurrentFrame()
709 @return A reference to ouer current active taskchild.
711 @onerror A null reference is returned.
713 *//*-*************************************************************************************************************/
714 css::uno::Reference
< css::frame::XTask
> SAL_CALL
Desktop::getActiveTask() throw( css::uno::RuntimeException
)
717 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
719 return css::uno::Reference< css::frame::XTask >( m_aChildTaskContainer.getActive(), css::uno::UNO_QUERY );
721 LOG_WARNING("Desktop::getActiveTask()", "Use of obsolete interface XTaskSupplier")
725 /*-************************************************************************************************************//**
726 @interface XDispatchProvider
727 @short search a dispatcher for given URL
728 @descr We use a helper implementation (class DispatchProvider) to do so.
729 So we don't must implement this algorithm twice!
731 @attention We don't need any lock here. Our helper is threadsafe himself and live, if we live!
733 @seealso class DispatchProvider
735 @param "aURL" , URL to dispatch
736 @param "sTargetFrameName" , name of target frame, who should dispatch these URL
737 @param "nSearchFlags" , flags to regulate the search
738 @param "lQueries" , list of queryDispatch() calls!
739 @return A reference or list of founded dispatch objects for these URL.
741 @onerror A null reference is returned.
743 *//*-*************************************************************************************************************/
744 css::uno::Reference
< css::frame::XDispatch
> SAL_CALL
Desktop::queryDispatch( const css::util::URL
& aURL
,
745 const ::rtl::OUString
& sTargetFrameName
,
746 sal_Int32 nSearchFlags
) throw( css::uno::RuntimeException
)
748 const char UNO_PROTOCOL
[] = ".uno:";
750 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
751 // Register transaction and reject wrong calls.
752 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
754 // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
755 // in our hash map. All other protocols are stored with the protocol part.
756 String
aCommand( aURL
.Main
);
757 if ( aURL
.Protocol
.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL
, sizeof( UNO_PROTOCOL
)-1 ))
758 aCommand
= aURL
.Path
;
760 // Make hash_map lookup if the current URL is in the disabled list
761 if ( m_aCommandOptions
.Lookup( SvtCommandOptions::CMDOPTION_DISABLED
, aCommand
) )
762 return css::uno::Reference
< css::frame::XDispatch
>();
765 // We use a helper to support these interface and an interceptor mechanism.
766 // Our helper is threadsafe by himself!
767 return m_xDispatchHelper
->queryDispatch( aURL
, sTargetFrameName
, nSearchFlags
);
771 //*****************************************************************************************************************
772 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
)
774 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
775 // Register transaction and reject wrong calls.
776 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
778 return m_xDispatchHelper
->queryDispatches( lQueries
);
781 /*-************************************************************************************************************//**
782 @interface XDipsatchProviderInterception
783 @short supports registration/deregistration of interception objects, which
784 are interested on special dispatches.
786 @descr Its realy provided by an internal helper, which is used inside the dispatch api too.
788 the interceptor object, which wish to be (de)registered.
791 *//*-*************************************************************************************************************/
792 void SAL_CALL
Desktop::registerDispatchProviderInterceptor( const css::uno::Reference
< css::frame::XDispatchProviderInterceptor
>& xInterceptor
)
793 throw( css::uno::RuntimeException
)
795 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
797 css::uno::Reference
< css::frame::XDispatchProviderInterception
> xInterceptionHelper( m_xDispatchHelper
, css::uno::UNO_QUERY
);
798 xInterceptionHelper
->registerDispatchProviderInterceptor( xInterceptor
);
801 //*****************************************************************************************************************
802 void SAL_CALL
Desktop::releaseDispatchProviderInterceptor ( const css::uno::Reference
< css::frame::XDispatchProviderInterceptor
>& xInterceptor
)
803 throw( css::uno::RuntimeException
)
805 TransactionGuard
aTransaction( m_aTransactionManager
, E_SOFTEXCEPTIONS
);
807 css::uno::Reference
< css::frame::XDispatchProviderInterception
> xInterceptionHelper( m_xDispatchHelper
, css::uno::UNO_QUERY
);
808 xInterceptionHelper
->releaseDispatchProviderInterceptor( xInterceptor
);
811 /*-************************************************************************************************************//**
812 @interface XFramesSupplier
813 @short return access to append or remove childs on desktop
814 @descr We don't implement these interface directly. We use a helper class to do this.
815 If you wish to add or delete childs to/from the container, call these method to get
816 a reference to the helper.
818 @attention Helper is threadsafe himself. So we don't need any lock here.
820 @seealso class OFrames
823 @return A reference to the helper.
825 @onerror A null reference is returned.
827 *//*-*************************************************************************************************************/
828 css::uno::Reference
< css::frame::XFrames
> SAL_CALL
Desktop::getFrames() throw( css::uno::RuntimeException
)
830 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
831 // Register transaction and reject wrong calls.
832 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
834 return m_xFramesHelper
;
837 /*-************************************************************************************************************//**
838 @interface XFramesSupplier
839 @short set/get the current active child frame
840 @descr It must be a task. Direct childs of desktop are tasks only! No frames are accepted.
841 We don't save this information directly in this class. We use ouer container-helper
844 @attention Helper is threadsafe himself. So we don't need any lock here.
846 @seealso class OFrameContainer
848 @param "xFrame", new active frame (must be valid!)
849 @return A reference to ouer current active childtask, if anyone exist.
851 @onerror A null reference is returned.
853 *//*-*************************************************************************************************************/
854 void SAL_CALL
Desktop::setActiveFrame( const css::uno::Reference
< css::frame::XFrame
>& xFrame
) throw( css::uno::RuntimeException
)
856 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
857 // Register transaction and reject wrong calls.
858 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
860 // Get old active frame first.
861 // If nothing will change - do nothing!
862 // Otherwise set new active frame ...
863 // and deactivate last frame.
864 // It's neccessary for our FrameActionEvent listener on a frame!
865 css::uno::Reference
< css::frame::XFrame
> xLastActiveChild
= m_aChildTaskContainer
.getActive();
866 if( xLastActiveChild
!= xFrame
)
868 m_aChildTaskContainer
.setActive( xFrame
);
869 if( xLastActiveChild
.is() == sal_True
)
871 xLastActiveChild
->deactivate();
876 //*****************************************************************************************************************
877 css::uno::Reference
< css::frame::XFrame
> SAL_CALL
Desktop::getActiveFrame() throw( css::uno::RuntimeException
)
879 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
880 // Register transaction and reject wrong calls.
881 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
883 return m_aChildTaskContainer
.getActive();
886 /*-************************************************************************************************************//**
888 @short non implemented methods!
889 @descr Some method make no sense for our desktop! He has no window or parent or ...
890 So we should implement it empty and warn programmer, if he use it!
899 *//*-*************************************************************************************************************/
900 void SAL_CALL
Desktop::initialize( const css::uno::Reference
< css::awt::XWindow
>& ) throw( css::uno::RuntimeException
)
904 //*****************************************************************************************************************
905 css::uno::Reference
< css::awt::XWindow
> SAL_CALL
Desktop::getContainerWindow() throw( css::uno::RuntimeException
)
907 return css::uno::Reference
< css::awt::XWindow
>();
910 //*****************************************************************************************************************
911 void SAL_CALL
Desktop::setCreator( const css::uno::Reference
< css::frame::XFramesSupplier
>& /*xCreator*/ ) throw( css::uno::RuntimeException
)
915 //*****************************************************************************************************************
916 css::uno::Reference
< css::frame::XFramesSupplier
> SAL_CALL
Desktop::getCreator() throw( css::uno::RuntimeException
)
918 return css::uno::Reference
< css::frame::XFramesSupplier
>();
921 //*****************************************************************************************************************
922 ::rtl::OUString SAL_CALL
Desktop::getName() throw( css::uno::RuntimeException
)
925 ReadGuard
aReadLock( m_aLock
);
930 //*****************************************************************************************************************
931 void SAL_CALL
Desktop::setName( const ::rtl::OUString
& sName
) throw( css::uno::RuntimeException
)
934 WriteGuard
aWriteLock( m_aLock
);
940 //*****************************************************************************************************************
941 sal_Bool SAL_CALL
Desktop::isTop() throw( css::uno::RuntimeException
)
946 //*****************************************************************************************************************
947 void SAL_CALL
Desktop::activate() throw( css::uno::RuntimeException
)
949 // Desktop is activae always ... but sometimes our frames try to activate
950 // the complete path from bottom to top ... And our desktop is the topest frame :-(
951 // So - please don't show any assertions here. Do nothing!
954 //*****************************************************************************************************************
955 void SAL_CALL
Desktop::deactivate() throw( css::uno::RuntimeException
)
957 // Desktop is activae always ... but sometimes our frames try to deactivate
958 // the complete path from bottom to top ... And our desktop is the topest frame :-(
959 // So - please don't show any assertions here. Do nothing!
962 //*****************************************************************************************************************
963 sal_Bool SAL_CALL
Desktop::isActive() throw( css::uno::RuntimeException
)
968 //*****************************************************************************************************************
969 sal_Bool SAL_CALL
Desktop::setComponent( const css::uno::Reference
< css::awt::XWindow
>& /*xComponentWindow*/ ,
970 const css::uno::Reference
< css::frame::XController
>& /*xController*/ ) throw( css::uno::RuntimeException
)
975 //*****************************************************************************************************************
976 css::uno::Reference
< css::awt::XWindow
> SAL_CALL
Desktop::getComponentWindow() throw( css::uno::RuntimeException
)
978 return css::uno::Reference
< css::awt::XWindow
>();
981 //*****************************************************************************************************************
982 css::uno::Reference
< css::frame::XController
> SAL_CALL
Desktop::getController() throw( css::uno::RuntimeException
)
984 return css::uno::Reference
< css::frame::XController
>();
987 //*****************************************************************************************************************
988 void SAL_CALL
Desktop::contextChanged() throw( css::uno::RuntimeException
)
992 //*****************************************************************************************************************
993 void SAL_CALL
Desktop::addFrameActionListener( const css::uno::Reference
< css::frame::XFrameActionListener
>& ) throw( css::uno::RuntimeException
)
997 //*****************************************************************************************************************
998 // css::frame::XFrame
999 //*****************************************************************************************************************
1000 void SAL_CALL
Desktop::removeFrameActionListener( const css::uno::Reference
< css::frame::XFrameActionListener
>& ) throw( css::uno::RuntimeException
)
1004 /*-************************************************************************************************************//**
1006 @short try to find a frame with special parameters
1007 @descr This method searches for a frame with the specified name.
1008 Frames may contain other frames (e.g. a frameset) and may
1009 be contained in other frames. This hierarchie ist searched by
1011 First some special names are taken into account, i.e. "",
1012 "_self", "_top", "_parent" etc. The FrameSearchFlags are ignored
1013 when comparing these names with aTargetFrameName, further steps are
1014 controlled by the FrameSearchFlags. If allowed, the name of the frame
1015 itself is compared with the desired one, then ( again if allowed )
1016 the method findFrame is called for all children of the frame.
1017 If no Frame with the given name is found until the top frames container,
1018 a new top Frame is created, if this is allowed by a special
1019 FrameSearchFlag. The new Frame also gets the desired name.
1020 We use a helper to get right search direction and react in a right manner.
1022 @seealso class TargetFinder
1024 @param "sTargetFrameName" , name of searched frame
1025 @param "nSearchFlags" , flags to regulate search
1026 @return A reference to an existing frame in hierarchy, if it exist.
1028 @onerror A null reference is returned.
1030 *//*-*************************************************************************************************************/
1031 css::uno::Reference
< css::frame::XFrame
> SAL_CALL
Desktop::findFrame( const ::rtl::OUString
& sTargetFrameName
,
1032 sal_Int32 nSearchFlags
) throw( css::uno::RuntimeException
)
1034 css::uno::Reference
< css::frame::XFrame
> xTarget
;
1036 //-----------------------------------------------------------------------------------------------------
1037 // 0) Ignore wrong parameter!
1038 // We doesn't support search for following special targets.
1039 // If we reject this requests - we mustnt check for such names
1040 // in following code again and again. If we do not so -wrong
1041 // search results can occure!
1042 //-----------------------------------------------------------------------------------------------------
1044 (sTargetFrameName
==SPECIALTARGET_DEFAULT
) || // valid for dispatches - not for findFrame()!
1045 (sTargetFrameName
==SPECIALTARGET_MENUBAR
) || // valid for dispatches - not for findFrame()!
1046 (sTargetFrameName
==SPECIALTARGET_HELPAGENT
) || // valid for dispatches - not for findFrame()!
1047 (sTargetFrameName
==SPECIALTARGET_PARENT
) || // we have no parent by definition
1048 (sTargetFrameName
==SPECIALTARGET_BEAMER
) // beamer frames are allowed as child of tasks only -
1049 // and they exist more then ones. We have no idea which our sub tasks is the right one
1055 //-----------------------------------------------------------------------------------------------------
1056 // I) check for special defined targets first which must be handled exclusive.
1057 // force using of "if() else if() ..."
1058 //-----------------------------------------------------------------------------------------------------
1060 // get threadsafe some neccessary member which are neccessary for following functionality
1062 ReadGuard
aReadLock( m_aLock
);
1063 css::uno::Reference
< css::lang::XMultiServiceFactory
> xFactory
= m_xFactory
;
1067 //-----------------------------------------------------------------------------------------------------
1069 // create a new task as child of this desktop instance
1070 // Note: Used helper TaskCreator use us automaticly ...
1071 //-----------------------------------------------------------------------------------------------------
1072 if ( sTargetFrameName
==SPECIALTARGET_BLANK
)
1074 TaskCreator
aCreator(xFactory
);
1075 xTarget
= aCreator
.createTask(sTargetFrameName
,sal_False
);
1078 //-----------------------------------------------------------------------------------------------------
1080 // We are top by definition
1081 //-----------------------------------------------------------------------------------------------------
1083 if ( sTargetFrameName
==SPECIALTARGET_TOP
)
1088 //-----------------------------------------------------------------------------------------------------
1089 // I.III) "_self", ""
1090 // This mean this "frame" in every case.
1091 //-----------------------------------------------------------------------------------------------------
1094 ( sTargetFrameName
==SPECIALTARGET_SELF
) ||
1095 ( sTargetFrameName
.getLength()<1 )
1103 //-------------------------------------------------------------------------------------------------
1104 // II) otherwhise use optional given search flags
1105 // force using of combinations of such flags. means no "else" part of use if() statements.
1106 // But we ust break further searches if target was already found.
1107 // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
1108 // TASK and CREATE are handled special.
1109 // But note: Such flags are not valid for the desktop - especialy SIBLINGS or PARENT.
1110 //-------------------------------------------------------------------------------------------------
1112 // get threadsafe some neccessary member which are neccessary for following functionality
1115 ::rtl::OUString sOwnName
= m_sName
;
1119 //-------------------------------------------------------------------------------------------------
1121 // Check for right name. If it's the searched one return ourself - otherwhise
1122 // ignore this flag.
1123 //-------------------------------------------------------------------------------------------------
1125 (nSearchFlags
& css::frame::FrameSearchFlag::SELF
) &&
1126 (sOwnName
== sTargetFrameName
)
1132 //-------------------------------------------------------------------------------------------------
1134 // This is a special flag. Normaly it regulate search inside tasks and forbid access to parent trees.
1135 // But the desktop exists outside such task trees. They are our sub trees. So the desktop implement
1136 // a special feature: We use it to start search on our direct childrens only. That means we supress
1137 // search on ALL child frames. May that can be usefull to get access on opened document tasks
1138 // only without filter out all non realy required sub frames ...
1139 // Used helper method on our container doesn't create any frame - its a search only.
1140 //-------------------------------------------------------------------------------------------------
1142 ( ! xTarget
.is() ) &&
1143 (nSearchFlags
& css::frame::FrameSearchFlag::TASKS
)
1146 xTarget
= m_aChildTaskContainer
.searchOnDirectChildrens(sTargetFrameName
);
1149 //-------------------------------------------------------------------------------------------------
1151 // Search on all children for the given target name.
1152 // An empty name value can't occure here - because it must be already handled as "_self"
1153 // before. Used helper function of container doesn't create any frame.
1154 // It makes a deep search only.
1155 //-------------------------------------------------------------------------------------------------
1157 ( ! xTarget
.is() ) &&
1158 (nSearchFlags
& css::frame::FrameSearchFlag::CHILDREN
)
1161 xTarget
= m_aChildTaskContainer
.searchOnAllChildrens(sTargetFrameName
);
1164 //-------------------------------------------------------------------------------------------------
1166 // If we haven't found any valid target frame by using normal flags - but user allowed us to create
1167 // a new one ... we should do that. Used TaskCreator use us automaticly as parent!
1168 //-------------------------------------------------------------------------------------------------
1170 ( ! xTarget
.is() ) &&
1171 (nSearchFlags
& css::frame::FrameSearchFlag::CREATE
)
1174 TaskCreator
aCreator(xFactory
);
1175 xTarget
= aCreator
.createTask(sTargetFrameName
,sal_False
);
1182 //=============================================================================
1183 void SAL_CALL
Desktop::dispose()
1184 throw( css::uno::RuntimeException
)
1186 // Safe impossible cases
1187 // It's an programming error if dispose is called before terminate!
1188 LOG_ASSERT2( m_bIsTerminated
==sal_False
, "Desktop::dispose()", "It's not allowed to dispose the desktop before terminate() is called!" )
1191 WriteGuard
aWriteLock( m_aLock
);
1193 // Look for multiple calls of this method!
1194 // If somewhere call dispose() twice - he will be stopped here realy!!!
1195 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1197 // Now - we are alone and its the first call of this method ...
1198 // otherwise call before had thrown a DisposedException / hopefully .-)
1199 // But we dont use the transaction object created before ... we reset it immediatly ...
1200 // two lines of code ... for what ?
1201 // The answer: We wished to synchronize concurrent dispose() calls -> OK
1202 // But next line will wait for all currently running transaction (even if they
1203 // are running within the same thread!) So we would block ourself there if aTransaction
1204 // will stay registered .-)
1205 aTransaction
.stop();
1207 // Disable this instance for further work.
1208 // This will wait for all current running transactions ...
1209 // and reject all new incoming requests!
1210 m_aTransactionManager
.setWorkingMode( E_BEFORECLOSE
);
1212 aWriteLock
.unlock();
1215 // Following lines of code can be called outside a synchronized block ...
1216 // Because our transaction manager will block all new requests to this object.
1217 // So nobody can use us any longer.
1218 // Exception: Only removing of listener will work ... and this code cant be dangerous.
1220 // First we has to kill all listener connections.
1221 // They might rely on our member and can hinder us on releasing them.
1222 css::uno::Reference
< css::uno::XInterface
> xThis ( static_cast< ::cppu::OWeakObject
* >(this), css::uno::UNO_QUERY
);
1223 css::lang::EventObject
aEvent( xThis
);
1224 m_aListenerContainer
.disposeAndClear( aEvent
);
1226 // Clear our child task container and forget all task references hardly.
1227 // Normaly all open document was already closed by our terminate() function before ...
1228 // New opened frames will have a problem now .-)
1229 m_aChildTaskContainer
.clear();
1231 // Dispose our helper too.
1232 css::uno::Reference
< css::lang::XEventListener
> xFramesHelper( m_xFramesHelper
, css::uno::UNO_QUERY
);
1233 if( xFramesHelper
.is() )
1234 xFramesHelper
->disposing( aEvent
);
1236 // At least clean up other member references.
1237 m_xDispatchHelper
.clear();
1238 m_xFramesHelper
.clear();
1239 m_xLastFrame
.clear();
1242 m_xPipeTerminator
.clear();
1243 m_xQuickLauncher
.clear();
1244 m_xSWThreadManager
.clear();
1245 m_xSfxTerminator
.clear();
1247 // From this point nothing will work further on this object ...
1248 // excepting our dtor() .-)
1249 m_aTransactionManager
.setWorkingMode( E_CLOSE
);
1252 /*-************************************************************************************************************//**
1253 @interface XComponent
1254 @short add/remove listener for dispose events
1255 @descr Add an event listener to this object, if you whish to get informations
1257 You must releas ethis listener reference during your own disposing() method.
1259 @attention Our container is threadsafe himeslf. So we doesn't need any lock here.
1263 @param "xListener", reference to valid listener. We don't accept invalid values!
1268 *//*-*************************************************************************************************************/
1269 void SAL_CALL
Desktop::addEventListener( const css::uno::Reference
< css::lang::XEventListener
>& xListener
) throw( css::uno::RuntimeException
)
1271 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1272 // Safe impossible cases
1273 // Method not defined for all incoming parameter.
1274 LOG_ASSERT2( implcp_addEventListener( xListener
), "Desktop::addEventListener()", "Invalid parameter detected!" )
1275 // Register transaction and reject wrong calls.
1276 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1278 m_aListenerContainer
.addInterface( ::getCppuType( ( const css::uno::Reference
< css::lang::XEventListener
>*) NULL
), xListener
);
1281 //*****************************************************************************************************************
1282 void SAL_CALL
Desktop::removeEventListener( const css::uno::Reference
< css::lang::XEventListener
>& xListener
) throw( css::uno::RuntimeException
)
1284 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1285 // Safe impossible cases
1286 // Method not defined for all incoming parameter.
1287 LOG_ASSERT2( implcp_removeEventListener( xListener
), "Desktop::removeEventListener()", "Invalid parameter detected!" )
1288 // Register transaction and reject wrong calls.
1289 TransactionGuard
aTransaction( m_aTransactionManager
, E_SOFTEXCEPTIONS
);
1291 m_aListenerContainer
.removeInterface( ::getCppuType( ( const css::uno::Reference
< css::lang::XEventListener
>*) NULL
), xListener
);
1294 /*-************************************************************************************************************//**
1295 @interface XDispatchResultListener
1296 @short callback for dispatches
1297 @descr To support our method "loadComponentFromURL()" we are listener on temp. created dispatcher.
1298 They call us back in this method "statusChanged()". As source of given state event, they give us a
1299 reference to the target frame, in which dispatch was loaded! So we can use it to return his component
1300 to caller! If no target exist ... ??!!
1302 @seealso method loadComponentFromURL()
1304 @param "aEvent", state event which (hopefully) valid informations
1309 *//*-*************************************************************************************************************/
1310 void SAL_CALL
Desktop::dispatchFinished( const css::frame::DispatchResultEvent
& aEvent
) throw( css::uno::RuntimeException
)
1312 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1313 // Register transaction and reject wrong calls.
1314 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1316 /* SAFE AREA ------------------------------------------------------------------------------------------- */
1317 WriteGuard
aWriteLock( m_aLock
);
1318 if( m_eLoadState
!= E_INTERACTION
)
1320 m_xLastFrame
= css::uno::Reference
< css::frame::XFrame
>();
1321 m_eLoadState
= E_FAILED
;
1322 if( aEvent
.State
== css::frame::DispatchResultState::SUCCESS
)
1324 css::uno::Reference
< css::frame::XFrame
> xFrame
;
1325 if ( aEvent
.Result
>>= m_xLastFrame
)
1326 m_eLoadState
= E_SUCCESSFUL
;
1329 /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
1332 /*-************************************************************************************************************//**
1333 @interface XEventListener
1334 @short not implemented!
1335 @descr We are a status listener ... and so we must be an event listener too ... But we doesn't need it realy!
1336 We are a temp. listener only and our lifetime isn't smaller then of our temp. used dispatcher.
1338 @seealso method loadComponentFromURL()
1345 *//*-*************************************************************************************************************/
1346 void SAL_CALL
Desktop::disposing( const css::lang::EventObject
& ) throw( css::uno::RuntimeException
)
1348 LOG_ERROR( "Desktop::disposing()", "Algorithm error! Normaly desktop is temp. listener ... not all the time. So this method shouldn't be called." )
1351 /*-************************************************************************************************************//**
1352 @interface XInteractionHandler
1353 @short callback for loadComponentFromURL for detected exceptions during load proccess
1354 @descr In this case we must cancel loading and throw these detected exception again as result
1355 of our own called method.
1358 Normal loop in loadComponentFromURL() breaks on setted member m_eLoadState during callback statusChanged().
1359 But these interaction feature implements second way to do so! So we must look on different callbacks
1360 for same operation ... and live with it.
1362 Search for given continuations too. If any XInteractionAbort exist ... use it to abort further operations
1363 for currently running operation!
1365 @seealso method loadComponentFromURL()
1366 @seealso member m_eLoadState
1368 @param "xRequest", request for interaction - normal a wrapped target exception from bottom services
1373 *//*-*************************************************************************************************************/
1374 void SAL_CALL
Desktop::handle( const css::uno::Reference
< css::task::XInteractionRequest
>& xRequest
) throw( css::uno::RuntimeException
)
1376 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1377 // Register transaction and reject wrong calls.
1378 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1380 // Don't check incoming request!
1381 // If somewhere starts interaction without right parameter - he maked something wrong.
1382 // loadComponentFromURL() waits for thjese event - otherwise it yield for ever!
1384 // get packed request and work on it first
1385 // Attention: Don't set it on internal member BEFORE interaction is finished - because
1386 // "loadComponentFromURL()" yield tills this member is changed. If we do it before
1387 // interaction finish we can't guarantee right functionality. May be we cancel load process to erliear ...
1388 css::uno::Any aRequest
= xRequest
->getRequest();
1390 // extract continuations from request
1391 css::uno::Sequence
< css::uno::Reference
< css::task::XInteractionContinuation
> > lContinuations
= xRequest
->getContinuations();
1392 css::uno::Reference
< css::task::XInteractionAbort
> xAbort
;
1393 css::uno::Reference
< css::task::XInteractionApprove
> xApprove
;
1394 css::uno::Reference
< css::document::XInteractionFilterSelect
> xFilterSelect
;
1395 sal_Bool bAbort
= sal_False
;
1397 sal_Int32 nCount
=lContinuations
.getLength();
1398 for( sal_Int32 nStep
=0; nStep
<nCount
; ++nStep
)
1401 xAbort
= css::uno::Reference
< css::task::XInteractionAbort
>( lContinuations
[nStep
], css::uno::UNO_QUERY
);
1403 if( ! xApprove
.is() )
1404 xApprove
= css::uno::Reference
< css::task::XInteractionApprove
>( lContinuations
[nStep
], css::uno::UNO_QUERY
);
1406 if( ! xFilterSelect
.is() )
1407 xFilterSelect
= css::uno::Reference
< css::document::XInteractionFilterSelect
>( lContinuations
[nStep
], css::uno::UNO_QUERY
);
1410 // differ between abortable interactions (error, unknown filter ...)
1411 // and other ones (ambigous but not unknown filter ...)
1412 css::task::ErrorCodeRequest aErrorCodeRequest
;
1413 css::document::AmbigousFilterRequest aAmbigousFilterRequest
;
1414 if( aRequest
>>= aAmbigousFilterRequest
)
1416 if( xFilterSelect
.is() )
1418 xFilterSelect
->setFilter( aAmbigousFilterRequest
.SelectedFilter
); // user selected filter wins!
1419 xFilterSelect
->select();
1423 if( aRequest
>>= aErrorCodeRequest
)
1425 sal_Bool bWarning
= ((aErrorCodeRequest
.ErrCode
& ERRCODE_WARNING_MASK
) == ERRCODE_WARNING_MASK
);
1426 if (xApprove
.is() && bWarning
)
1442 /* SAFE AREA ------------------------------------------------------------------------------------------- */
1443 // Ok now it's time to break yield loop of loadComponentFromURL().
1444 // But only for realy aborted requests!
1445 // For example warnings will be approved and we wait for any success story ...
1448 WriteGuard
aWriteLock( m_aLock
);
1449 m_eLoadState
= E_INTERACTION
;
1450 m_aInteractionRequest
= aRequest
;
1451 aWriteLock
.unlock();
1453 /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
1456 //-----------------------------------------------------------------------------
1457 ::sal_Int32 SAL_CALL
Desktop::leaseNumber( const css::uno::Reference
< css::uno::XInterface
>& xComponent
)
1458 throw (css::lang::IllegalArgumentException
,
1459 css::uno::RuntimeException
)
1461 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1462 return m_xTitleNumberGenerator
->leaseNumber (xComponent
);
1465 //-----------------------------------------------------------------------------
1466 void SAL_CALL
Desktop::releaseNumber( ::sal_Int32 nNumber
)
1467 throw (css::lang::IllegalArgumentException
,
1468 css::uno::RuntimeException
)
1470 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1471 m_xTitleNumberGenerator
->releaseNumber (nNumber
);
1474 //-----------------------------------------------------------------------------
1475 void SAL_CALL
Desktop::releaseNumberForComponent( const css::uno::Reference
< css::uno::XInterface
>& xComponent
)
1476 throw (css::lang::IllegalArgumentException
,
1477 css::uno::RuntimeException
)
1479 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1480 m_xTitleNumberGenerator
->releaseNumberForComponent (xComponent
);
1483 //-----------------------------------------------------------------------------
1484 ::rtl::OUString SAL_CALL
Desktop::getUntitledPrefix()
1485 throw (css::uno::RuntimeException
)
1487 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1488 return m_xTitleNumberGenerator
->getUntitledPrefix ();
1491 /*-************************************************************************************************************//**
1492 @short try to convert a property value
1493 @descr This method is called from helperclass "OPropertySetHelper".
1494 Don't use this directly!
1495 You must try to convert the value of given DESKTOP_PROPHANDLE and
1496 return results of this operation. This will be used to ask vetoable
1497 listener. If no listener has a veto, we will change value realy!
1498 ( in method setFastPropertyValue_NoBroadcast(...) )
1500 @attention Methods of OPropertySethelper are safed by using our shared osl mutex! (see ctor!)
1501 So we must use different locks to make our implementation threadsafe.
1503 @seealso class OPropertySetHelper
1504 @seealso method setFastPropertyValue_NoBroadcast()
1506 @param "aConvertedValue" new converted value of property
1507 @param "aOldValue" old value of property
1508 @param "nHandle" handle of property
1509 @param "aValue" new value of property
1510 @return sal_True if value will be changed, sal_FALSE otherway
1512 @onerror IllegalArgumentException, if you call this with an invalid argument
1514 *//*-*************************************************************************************************************/
1515 sal_Bool SAL_CALL
Desktop::convertFastPropertyValue( css::uno::Any
& aConvertedValue
,
1516 css::uno::Any
& aOldValue
,
1518 const css::uno::Any
& aValue
) throw( css::lang::IllegalArgumentException
)
1520 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1521 // Register transaction and reject wrong calls.
1522 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1524 // Initialize state with FALSE !!!
1525 // (Handle can be invalid)
1526 sal_Bool bReturn
= sal_False
;
1530 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO
:
1531 bReturn
= PropHelper::willPropertyBeChanged(
1532 css::uno::makeAny(m_bSuspendQuickstartVeto
),
1537 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER
:
1538 bReturn
= PropHelper::willPropertyBeChanged(
1539 css::uno::makeAny(m_xDispatchRecorderSupplier
),
1544 case DESKTOP_PROPHANDLE_TITLE
:
1545 bReturn
= PropHelper::willPropertyBeChanged(
1546 css::uno::makeAny(m_sTitle
),
1553 // Return state of operation.
1557 /*-************************************************************************************************************//**
1558 @short set value of a transient property
1559 @descr This method is calling from helperclass "OPropertySetHelper".
1560 Don't use this directly!
1561 Handle and value are valid everyway! You must set the new value only.
1562 After this, baseclass send messages to all listener automaticly.
1564 @seealso class OPropertySetHelper
1566 @param "nHandle" handle of property to change
1567 @param "aValue" new value of property
1570 @onerror An exception is thrown.
1572 *//*-*************************************************************************************************************/
1573 void SAL_CALL
Desktop::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
,
1574 const css::uno::Any
& aValue
) throw( css::uno::Exception
)
1576 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1577 // Register transaction and reject wrong calls.
1578 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1582 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO
: aValue
>>= m_bSuspendQuickstartVeto
;
1584 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER
: aValue
>>= m_xDispatchRecorderSupplier
;
1586 case DESKTOP_PROPHANDLE_TITLE
: aValue
>>= m_sTitle
;
1591 /*-************************************************************************************************************//**
1592 @short get value of a transient property
1593 @descr This method is calling from helperclass "OPropertySetHelper".
1594 Don't use this directly!
1596 @attention We don't need any mutex or lock here ... We use threadsafe container or methods here only!
1598 @seealso class OPropertySetHelper
1600 @param "nHandle" handle of property to change
1601 @param "aValue" current value of property
1606 *//*-*************************************************************************************************************/
1607 void SAL_CALL
Desktop::getFastPropertyValue( css::uno::Any
& aValue
,
1608 sal_Int32 nHandle
) const
1610 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1611 // Register transaction and reject wrong calls.
1612 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1616 case DESKTOP_PROPHANDLE_ACTIVEFRAME
: aValue
<<= m_aChildTaskContainer
.getActive();
1618 case DESKTOP_PROPHANDLE_ISPLUGGED
: aValue
<<= sal_False
;
1620 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO
: aValue
<<= m_bSuspendQuickstartVeto
;
1622 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER
: aValue
<<= m_xDispatchRecorderSupplier
;
1624 case DESKTOP_PROPHANDLE_TITLE
: aValue
<<= m_sTitle
;
1629 /*-************************************************************************************************************//**
1630 @short return structure and information about transient properties
1631 @descr This method is calling from helperclass "OPropertySetHelper".
1632 Don't use this directly!
1634 @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
1635 Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
1636 So we could have two different mutex/lock mechanism at the same object.
1638 @seealso class OPropertySetHelper
1641 @return structure with property-informations
1645 *//*-*************************************************************************************************************/
1646 ::cppu::IPropertyArrayHelper
& SAL_CALL
Desktop::getInfoHelper()
1648 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1649 // Register transaction and reject wrong calls.
1650 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1652 // Optimize this method !
1653 // We initialize a static variable only one time. And we don't must use a mutex at every call!
1654 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
1655 static ::cppu::OPropertyArrayHelper
* pInfoHelper
= NULL
;
1657 if( pInfoHelper
== NULL
)
1659 // Ready for multithreading
1660 ::osl::MutexGuard
aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
1661 // Control this pointer again, another instance can be faster then these!
1662 if( pInfoHelper
== NULL
)
1664 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
1665 // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
1666 // "sal_True" say: Table is sorted by name.
1667 static ::cppu::OPropertyArrayHelper
aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True
);
1668 pInfoHelper
= &aInfoHelper
;
1672 return(*pInfoHelper
);
1675 /*-************************************************************************************************************//**
1676 @short return propertysetinfo
1677 @descr You can call this method to get information about transient properties
1680 @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
1681 Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
1682 So we could have two different mutex/lock mechanism at the same object.
1684 @seealso class OPropertySetHelper
1685 @seealso interface XPropertySet
1686 @seealso interface XMultiPropertySet
1689 @return reference to object with information [XPropertySetInfo]
1693 *//*-*************************************************************************************************************/
1694 css::uno::Reference
< css::beans::XPropertySetInfo
> SAL_CALL
Desktop::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException
)
1696 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1697 // Register transaction and reject wrong calls.
1698 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1700 // Optimize this method !
1701 // We initialize a static variable only one time. And we don't must use a mutex at every call!
1702 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
1703 static css::uno::Reference
< css::beans::XPropertySetInfo
>* pInfo
= NULL
;
1707 // Ready for multithreading
1708 ::osl::MutexGuard
aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
1709 // Control this pointer again, another instance can be faster then these!
1712 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
1713 // (Use method "getInfoHelper()".)
1714 static css::uno::Reference
< css::beans::XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
1722 /*-************************************************************************************************************//**
1723 @short return current component of current frame
1724 @descr The desktop himself has no component. But every frame in subtree.
1725 If somewhere call getCurrentComponent() at this class, we try to find the right frame and
1726 then we try to become his component. It can be a VCL-component, the model or the controller
1729 @attention We don't work on internal member ... so we doesn't need any lock here.
1731 @seealso method getCurrentComponent();
1733 @param "xFrame", reference to valid frame in hierarchy. Method is not defined for invalid values.
1734 But we don't check these. Its an IMPL-method and caller must use it right!
1735 @return A reference to found component.
1737 @onerror A null reference is returned.
1739 *//*-*************************************************************************************************************/
1740 css::uno::Reference
< css::lang::XComponent
> Desktop::impl_getFrameComponent( const css::uno::Reference
< css::frame::XFrame
>& xFrame
) const
1742 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1743 // Register transaction and reject wrong calls.
1744 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1746 // Set default return value, if method failed.
1747 css::uno::Reference
< css::lang::XComponent
> xComponent
;
1748 // Does no controller exists?
1749 css::uno::Reference
< css::frame::XController
> xController
= xFrame
->getController();
1750 if( xController
.is() == sal_False
)
1752 // Controller not exist - use the VCL-component.
1753 xComponent
= css::uno::Reference
< css::lang::XComponent
>( xFrame
->getComponentWindow(), css::uno::UNO_QUERY
);
1757 // Does no model exists?
1758 css::uno::Reference
< css::frame::XModel
> xModel( xController
->getModel(), css::uno::UNO_QUERY
);
1759 if( xModel
.is() == sal_True
)
1761 // Model exist - use the model as component.
1762 xComponent
= css::uno::Reference
< css::lang::XComponent
>( xModel
, css::uno::UNO_QUERY
);
1766 // Model not exist - use the controller as component.
1767 xComponent
= css::uno::Reference
< css::lang::XComponent
>( xController
, css::uno::UNO_QUERY
);
1774 /*-************************************************************************************************************//**
1775 @short create table with information about properties
1776 @descr We use a helper class to support properties. These class need some information about this.
1777 These method create a new static description table with name, type, r/w-flags and so on ...
1779 @seealso class OPropertySetHelper
1780 @seealso method getInfoHelper()
1783 @return Static table with information about properties.
1787 *//*-*************************************************************************************************************/
1788 const css::uno::Sequence
< css::beans::Property
> Desktop::impl_getStaticPropertyDescriptor()
1790 // Create a new static property array to initialize sequence!
1791 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
1792 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
1793 // It's necessary for methods of OPropertySetHelper.
1795 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
1797 static const css::beans::Property pProperties
[] =
1799 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
),
1800 css::beans::Property( DESKTOP_PROPNAME_DISPATCHRECORDERSUPPLIER
, DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER
, ::getCppuType((const css::uno::Reference
< css::frame::XDispatchRecorderSupplier
>*)NULL
), css::beans::PropertyAttribute::TRANSIENT
),
1801 css::beans::Property( DESKTOP_PROPNAME_ISPLUGGED
, DESKTOP_PROPHANDLE_ISPLUGGED
, ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT
| css::beans::PropertyAttribute::READONLY
),
1802 css::beans::Property( DESKTOP_PROPNAME_SUSPENDQUICKSTARTVETO
, DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO
, ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT
),
1803 css::beans::Property( DESKTOP_PROPNAME_TITLE
, DESKTOP_PROPHANDLE_TITLE
, ::getCppuType((const ::rtl::OUString
*)NULL
) , css::beans::PropertyAttribute::TRANSIENT
),
1805 // Use it to initialize sequence!
1806 static const css::uno::Sequence
< css::beans::Property
> lPropertyDescriptor( pProperties
, DESKTOP_PROPCOUNT
);
1807 // Return static "PropertyDescriptor"
1808 return lPropertyDescriptor
;
1811 //=============================================================================
1812 void Desktop::impl_sendQueryTerminationEvent(Desktop::TTerminateListenerList
& lCalledListener
,
1817 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1819 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aListenerContainer
.getContainer( ::getCppuType( ( const css::uno::Reference
< css::frame::XTerminateListener
>*) NULL
) );
1823 css::lang::EventObject
aEvent( static_cast< ::cppu::OWeakObject
* >(this) );
1825 ::cppu::OInterfaceIteratorHelper
aIterator( *pContainer
);
1826 while ( aIterator
.hasMoreElements() )
1830 css::uno::Reference
< css::frame::XTerminateListener
> xListener(aIterator
.next(), css::uno::UNO_QUERY
);
1831 if ( ! xListener
.is() )
1833 xListener
->queryTermination( aEvent
);
1834 lCalledListener
.push_back(xListener
);
1836 catch( const css::frame::TerminationVetoException
& )
1838 // first veto will stop notification loop.
1842 catch( const css::uno::Exception
& )
1844 // clean up container.
1845 // E.g. dead remote listener objects can make trouble otherwise.
1846 // Iterator implementation allows removing objects during it's used !
1852 //=============================================================================
1853 void Desktop::impl_sendCancelTerminationEvent(const Desktop::TTerminateListenerList
& lCalledListener
)
1855 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1857 css::lang::EventObject
aEvent( static_cast< ::cppu::OWeakObject
* >(this) );
1858 Desktop::TTerminateListenerList::const_iterator pIt
;
1859 for ( pIt
= lCalledListener
.begin();
1860 pIt
!= lCalledListener
.end ();
1865 // Note: cancelTermination() is a new and optional interface method !
1866 css::uno::Reference
< css::frame::XTerminateListener
> xListener
= *pIt
;
1867 css::uno::Reference
< css::frame::XTerminateListener2
> xListenerGeneration2(xListener
, css::uno::UNO_QUERY
);
1868 if ( ! xListenerGeneration2
.is() )
1870 xListenerGeneration2
->cancelTermination( aEvent
);
1872 catch( const css::uno::Exception
& )
1877 //=============================================================================
1878 void Desktop::impl_sendNotifyTerminationEvent()
1880 TransactionGuard
aTransaction( m_aTransactionManager
, E_HARDEXCEPTIONS
);
1882 ::cppu::OInterfaceContainerHelper
* pContainer
= m_aListenerContainer
.getContainer( ::getCppuType( ( const css::uno::Reference
< css::frame::XTerminateListener
>*) NULL
) );
1886 css::lang::EventObject
aEvent( static_cast< ::cppu::OWeakObject
* >(this) );
1888 ::cppu::OInterfaceIteratorHelper
aIterator( *pContainer
);
1889 while ( aIterator
.hasMoreElements() )
1893 css::uno::Reference
< css::frame::XTerminateListener
> xListener(aIterator
.next(), css::uno::UNO_QUERY
);
1894 if ( ! xListener
.is() )
1896 xListener
->notifyTermination( aEvent
);
1898 catch( const css::uno::Exception
& )
1900 // clean up container.
1901 // E.g. dead remote listener objects can make trouble otherwise.
1902 // Iterator implementation allows removing objects during it's used !
1908 //=============================================================================
1909 ::sal_Bool
Desktop::impl_closeFrames(::sal_Bool bAllowUI
)
1912 ReadGuard
aReadLock( m_aLock
);
1913 css::uno::Sequence
< css::uno::Reference
< css::frame::XFrame
> > lFrames
= m_aChildTaskContainer
.getAllElements();
1917 ::sal_Int32 c
= lFrames
.getLength();
1919 ::sal_Int32 nNonClosedFrames
= 0;
1921 for( i
=0; i
<c
; ++i
)
1925 css::uno::Reference
< css::frame::XFrame
> xFrame
= lFrames
[i
];
1927 // XController.suspend() will show an UI ...
1928 // Use it in case it was allowed from outside only.
1929 sal_Bool bSuspended
= sal_False
;
1930 css::uno::Reference
< css::frame::XController
> xController( xFrame
->getController(), css::uno::UNO_QUERY
);
1933 ( xController
.is() )
1936 bSuspended
= xController
->suspend( sal_True
);
1944 // Try to close frame (in case no UI was allowed without calling XController->suspend() before!)
1945 // But don't deliver ownership to any other one!
1946 // This method can be called again.
1947 css::uno::Reference
< css::util::XCloseable
> xClose( xFrame
, css::uno::UNO_QUERY
);
1952 xClose
->close(sal_False
);
1954 catch(const css::util::CloseVetoException
&)
1956 // Any internal process of this frame disagree with our request.
1957 // Safe this state but dont break these loop. Other frames has to be closed!
1960 // Reactivate controller.
1961 // It can happen that XController.suspend() returned true ... but a registered close listener
1962 // throwed these veto exception. Then the controller has to be reactivated. Otherwise
1963 // these document doesnt work any more.
1968 xController
->suspend(sal_False
);
1971 // If interface XClosable interface exists and was used ...
1972 // it's not allowed to use XComponent->dispose() also !
1976 // XClosable not supported ?
1977 // Then we have to dispose these frame hardly.
1978 css::uno::Reference
< css::lang::XComponent
> xDispose( xFrame
, css::uno::UNO_QUERY
);
1979 if ( xDispose
.is() )
1980 xDispose
->dispose();
1982 // Don't remove these frame from our child container!
1983 // A frame do it by itself inside close()/dispose() method.
1985 catch(const css::lang::DisposedException
&)
1987 // Dispose frames are closed frames.
1988 // So we can count it here .-)
1992 return (nNonClosedFrames
< 1);
1995 //_________________________________________________________________________________________________________________
1997 //_________________________________________________________________________________________________________________
1999 /*-----------------------------------------------------------------------------------------------------------------
2000 The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
2001 we return "sal_True". (otherwise sal_False) This mechanism is used to throw an ASSERT!
2002 -----------------------------------------------------------------------------------------------------------------*/
2004 #ifdef ENABLE_ASSERTIONS
2006 //*****************************************************************************************************************
2007 // We work with valid servicemanager only.
2008 sal_Bool
Desktop::implcp_ctor( const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xFactory
)
2011 ( &xFactory
== NULL
) ||
2012 ( xFactory
.is() == sal_False
)
2016 //*****************************************************************************************************************
2017 // We work with valid listener only.
2018 sal_Bool
Desktop::implcp_addTerminateListener( const css::uno::Reference
< css::frame::XTerminateListener
>& xListener
)
2021 ( &xListener
== NULL
) ||
2022 ( xListener
.is() == sal_False
)
2026 //*****************************************************************************************************************
2027 // We work with valid listener only.
2028 sal_Bool
Desktop::implcp_removeTerminateListener( const css::uno::Reference
< css::frame::XTerminateListener
>& xListener
)
2031 ( &xListener
== NULL
) ||
2032 ( xListener
.is() == sal_False
)
2036 //*****************************************************************************************************************
2037 // The target frame could be ""(!), but flags must be in range of right enum.
2038 sal_Bool
Desktop::implcp_findFrame( const ::rtl::OUString
& sTargetFrameName
,
2039 sal_Int32 nSearchFlags
)
2042 ( &sTargetFrameName
== NULL
) ||
2044 ( nSearchFlags
!= css::frame::FrameSearchFlag::AUTO
) &&
2045 ( !( nSearchFlags
& css::frame::FrameSearchFlag::PARENT
) ) &&
2046 ( !( nSearchFlags
& css::frame::FrameSearchFlag::SELF
) ) &&
2047 ( !( nSearchFlags
& css::frame::FrameSearchFlag::CHILDREN
) ) &&
2048 ( !( nSearchFlags
& css::frame::FrameSearchFlag::CREATE
) ) &&
2049 ( !( nSearchFlags
& css::frame::FrameSearchFlag::SIBLINGS
) ) &&
2050 ( !( nSearchFlags
& css::frame::FrameSearchFlag::TASKS
) ) &&
2051 ( !( nSearchFlags
& css::frame::FrameSearchFlag::ALL
) ) &&
2052 ( !( nSearchFlags
& css::frame::FrameSearchFlag::GLOBAL
) )
2057 //*****************************************************************************************************************
2058 // We work with valid listener only.
2059 sal_Bool
Desktop::implcp_addEventListener( const css::uno::Reference
< css::lang::XEventListener
>& xListener
)
2062 ( &xListener
== NULL
) ||
2063 ( xListener
.is() == sal_False
)
2067 //*****************************************************************************************************************
2068 // We work with valid listener only.
2069 sal_Bool
Desktop::implcp_removeEventListener( const css::uno::Reference
< css::lang::XEventListener
>& xListener
)
2072 ( &xListener
== NULL
) ||
2073 ( xListener
.is() == sal_False
)
2077 //*****************************************************************************************************************
2078 sal_Bool
Desktop::implcp_statusChanged( const css::frame::FeatureStateEvent
& aEvent
)
2081 ( &aEvent
== NULL
) ||
2082 ( aEvent
.FeatureDescriptor
.getLength() < 1 )
2086 #endif // #ifdef ENABLE_ASSERTIONS
2088 } // namespace framework