Update ooo320-m1
[ooovba.git] / framework / source / services / desktop.cxx
blobfd983ed4921e6b901330d992471e4cf8b19f903b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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 //_________________________________________________________________________________________________________________
35 // my own includes
36 //_________________________________________________________________________________________________________________
37 #include <loadenv/loadenv.hxx>
39 #ifndef __FRAMEWORK_LOADENV_TARGETHELPER_HXX_
40 #include <loadenv/targethelper.hxx>
41 #endif
43 #ifndef __FRAMEWORK_DESKTOP_HXX_
44 #include <services/desktop.hxx>
45 #endif
46 #include <helper/ocomponentaccess.hxx>
47 #include <dispatch/dispatchprovider.hxx>
49 #ifndef __FRAMEWORK_DISPATCH_INTERCEPTIONHELPER_HXX_
50 #include <dispatch/interceptionhelper.hxx>
51 #endif
52 #include <classes/taskcreator.hxx>
53 #include <threadhelp/transactionguard.hxx>
54 #include <threadhelp/writeguard.hxx>
55 #include <threadhelp/readguard.hxx>
56 #include <services.h>
57 #include <general.h>
58 #include <properties.h>
60 #include <classes/resource.hrc>
61 #include <classes/fwkresid.hxx>
63 //_________________________________________________________________________________________________________________
64 // interface includes
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/lang/DisposedException.hpp>
86 #include <com/sun/star/util/XCloseable.hpp>
87 #include <com/sun/star/document/MacroExecMode.hpp>
88 #include <com/sun/star/document/UpdateDocMode.hpp>
89 #include <com/sun/star/frame/XTerminateListener2.hpp>
91 //_________________________________________________________________________________________________________________
92 // includes of other projects
93 //_________________________________________________________________________________________________________________
94 #include <cppuhelper/queryinterface.hxx>
95 #include <cppuhelper/typeprovider.hxx>
96 #include <cppuhelper/factory.hxx>
97 #include <cppuhelper/proptypehlp.hxx>
98 #include <rtl/ustrbuf.hxx>
99 #include <rtl/logfile.hxx>
100 #include <vcl/svapp.hxx>
102 #ifndef __RSC
103 #include <tools/errinf.hxx>
104 #endif
105 #include <comphelper/extract.hxx>
107 //_________________________________________________________________________________________________________________
108 // namespace
109 //_________________________________________________________________________________________________________________
111 namespace framework{
113 //_________________________________________________________________________________________________________________
114 // non exported const
115 //_________________________________________________________________________________________________________________
117 //_________________________________________________________________________________________________________________
118 // non exported definitions
119 //_________________________________________________________________________________________________________________
121 //_________________________________________________________________________________________________________________
122 // declarations
123 //_________________________________________________________________________________________________________________
125 //*****************************************************************************************************************
126 // XInterface, XTypeProvider, XServiceInfo
127 //*****************************************************************************************************************
128 DEFINE_XINTERFACE_15 ( Desktop ,
129 OWeakObject ,
130 DIRECT_INTERFACE( css::lang::XTypeProvider ),
131 DIRECT_INTERFACE( css::lang::XServiceInfo ),
132 DIRECT_INTERFACE( css::frame::XDesktop ),
133 DIRECT_INTERFACE( css::frame::XComponentLoader ),
134 DIRECT_INTERFACE( css::frame::XTasksSupplier ),
135 DIRECT_INTERFACE( css::frame::XDispatchProvider ),
136 DIRECT_INTERFACE( css::frame::XDispatchProviderInterception),
137 DIRECT_INTERFACE( css::frame::XFramesSupplier ),
138 DIRECT_INTERFACE( css::frame::XFrame ),
139 DIRECT_INTERFACE( css::lang::XComponent ),
140 DIRECT_INTERFACE( css::frame::XDispatchResultListener ),
141 DIRECT_INTERFACE( css::lang::XEventListener ),
142 DIRECT_INTERFACE( css::task::XInteractionHandler ),
143 DIRECT_INTERFACE( css::beans::XPropertySet ),
144 DIRECT_INTERFACE( css::frame::XUntitledNumbers )
147 DEFINE_XTYPEPROVIDER_15 ( Desktop ,
148 css::lang::XTypeProvider ,
149 css::lang::XServiceInfo ,
150 css::frame::XDesktop ,
151 css::frame::XComponentLoader ,
152 css::frame::XTasksSupplier ,
153 css::frame::XDispatchProvider ,
154 css::frame::XDispatchProviderInterception ,
155 css::frame::XFramesSupplier ,
156 css::frame::XFrame ,
157 css::lang::XComponent ,
158 css::frame::XDispatchResultListener ,
159 css::lang::XEventListener ,
160 css::task::XInteractionHandler ,
161 css::beans::XPropertySet ,
162 css::frame::XUntitledNumbers
165 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( Desktop ,
166 ::cppu::OWeakObject ,
167 SERVICENAME_DESKTOP ,
168 IMPLEMENTATIONNAME_DESKTOP
171 DEFINE_INIT_SERVICE ( Desktop,
173 /*Attention
174 I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
175 to create a new instance of this class by our own supported service factory.
176 see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
179 //-------------------------------------------------------------------------------------------------------------
180 // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
181 // We hold member as reference ... not as pointer too!
182 // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
183 // But look on dispose() for right order of deinitialization.
184 OFrames* pFramesHelper = new OFrames( m_xFactory, this, &m_aChildTaskContainer );
185 m_xFramesHelper = css::uno::Reference< css::frame::XFrames >( static_cast< ::cppu::OWeakObject* >(pFramesHelper), css::uno::UNO_QUERY );
187 //-------------------------------------------------------------------------------------------------------------
188 // Initialize a new dispatchhelper-object to handle dispatches.
189 // We use these helper as slave for our interceptor helper ... not directly!
190 // But he is event listener on THIS instance!
191 DispatchProvider* pDispatchHelper = new DispatchProvider( m_xFactory, this );
192 css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
194 //-------------------------------------------------------------------------------------------------------------
195 // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
196 // Set created dispatch provider as slowest slave of it.
197 // Hold interception helper by reference only - not by pointer!
198 // So it's easiear to destroy it.
199 InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
200 m_xDispatchHelper = css::uno::Reference< css::frame::XDispatchProvider >( static_cast< ::cppu::OWeakObject* >(pInterceptionHelper), css::uno::UNO_QUERY );
202 ::rtl::OUStringBuffer sUntitledPrefix (256);
203 sUntitledPrefix.append (::rtl::OUString( String( FwkResId( STR_UNTITLED_DOCUMENT ))));
204 sUntitledPrefix.appendAscii (" ");
206 ::comphelper::NumberedCollection* pNumbers = new ::comphelper::NumberedCollection ();
207 m_xTitleNumberGenerator = css::uno::Reference< css::frame::XUntitledNumbers >(static_cast< ::cppu::OWeakObject* >(pNumbers), css::uno::UNO_QUERY_THROW);
208 pNumbers->setOwner ( static_cast< ::cppu::OWeakObject* >(this) );
209 pNumbers->setUntitledPrefix ( sUntitledPrefix.makeStringAndClear () );
211 // Safe impossible cases
212 // We can't work without this helper!
213 LOG_ASSERT2( m_xFramesHelper.is ()==sal_False, "Desktop::Desktop()", "Frames helper is not valid. XFrames, XIndexAccess and XElementAcces are not supported!\n")
214 LOG_ASSERT2( m_xDispatchHelper.is()==sal_False, "Desktop::Desktop()", "Dispatch helper is not valid. XDispatch will not work correctly!\n" )
216 // Enable object for real working!
217 // Otherwise all calls will be rejected ...
218 m_aTransactionManager.setWorkingMode( E_WORK );
222 /*-************************************************************************************************************//**
223 @short standard constructor to create instance by factory
224 @descr This constructor initialize a new instance of this class by valid factory,
225 and will be set valid values on his member and baseclasses.
227 @attention a) Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
228 will get over this. (e.g. using of your reference as parameter to initialize some member)
229 Do such things in DEFINE_INIT_SERVICE() method, which is called automaticly after your ctor!!!
230 b) Baseclass OBroadcastHelper is a typedef in namespace cppu!
231 The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
232 If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
233 I don't know why! (other compiler not tested .. but it works!)
235 @seealso method DEFINE_INIT_SERVICE()
237 @param "xFactory" is the multi service manager, which create this instance.
238 The value must be different from NULL!
239 @return -
241 @onerror We throw an ASSERT in debug version or do nothing in relaese version.
242 *//*-*************************************************************************************************************/
243 Desktop::Desktop( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
244 // Init baseclasses first
245 // Attention: Don't change order of initialization!
246 // ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
247 // We must garant right initialization and a valid value of this to initialize other baseclasses!
248 : ThreadHelpBase ( &Application::GetSolarMutex() )
249 , TransactionBase ( )
250 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType > ( m_aLock.getShareableOslMutex() )
251 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
252 , ::cppu::OWeakObject ( )
253 // Init member
254 #ifdef ENABLE_ASSERTIONS
255 , m_bIsTerminated ( sal_False ) // see dispose() for further informations!
256 #endif
257 , m_xFactory ( xFactory )
258 , m_aChildTaskContainer ( )
259 , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
260 , m_xFramesHelper ( )
261 , m_xDispatchHelper ( )
262 , m_eLoadState ( E_NOTSET )
263 , m_xLastFrame ( )
264 , m_aInteractionRequest ( )
265 , m_bSuspendQuickstartVeto( sal_False )
266 , m_aCommandOptions ( )
267 , m_sName ( )
268 , m_sTitle ( )
269 , m_xDispatchRecorderSupplier( )
270 , m_xPipeTerminator ( )
271 , m_xQuickLauncher ( )
272 , m_xSWThreadManager ( )
273 , m_xSfxTerminator ( )
274 , m_xTitleNumberGenerator ( )
276 // Safe impossible cases
277 // We don't accept all incoming parameter.
278 LOG_ASSERT2( implcp_ctor( xFactory ), "Desktop::Desktop()", "Invalid parameter detected!")
281 /*-************************************************************************************************************//**
282 @short standard destructor
283 @descr This one do NOTHING! Use dispose() instaed of this.
285 @seealso method dispose()
287 @param -
288 @return -
290 @onerror -
291 *//*-*************************************************************************************************************/
292 Desktop::~Desktop()
294 LOG_ASSERT2( m_bIsTerminated ==sal_False, "Desktop::~Desktop()", "Who forgot to terminate the desktop service?" )
295 LOG_ASSERT2( m_aTransactionManager.getWorkingMode()!=E_CLOSE , "Desktop::~Desktop()", "Who forgot to dispose this service?" )
298 //=============================================================================
299 sal_Bool SAL_CALL Desktop::terminate()
300 throw( css::uno::RuntimeException )
302 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
304 SYNCHRONIZED_START
305 ReadGuard aReadLock( m_aLock );
307 css::uno::Reference< css::frame::XTerminateListener > xPipeTerminator = m_xPipeTerminator;
308 css::uno::Reference< css::frame::XTerminateListener > xQuickLauncher = m_xQuickLauncher;
309 css::uno::Reference< css::frame::XTerminateListener > xSWThreadManager = m_xSWThreadManager;
310 css::uno::Reference< css::frame::XTerminateListener > xSfxTerminator = m_xSfxTerminator;
312 css::lang::EventObject aEvent ( static_cast< ::cppu::OWeakObject* >(this) );
313 ::sal_Bool bAskQuickStart = !m_bSuspendQuickstartVeto ;
315 aReadLock.unlock();
316 SYNCHRONIZED_END
318 //-------------------------------------------------------------------------------------------------------------
319 // Ask normal terminate listener. They could stop terminate without closing any open document.
320 Desktop::TTerminateListenerList lCalledTerminationListener;
321 ::sal_Bool bVeto = sal_False;
322 impl_sendQueryTerminationEvent(lCalledTerminationListener, bVeto);
323 if ( bVeto )
325 impl_sendCancelTerminationEvent(lCalledTerminationListener);
326 return sal_False;
329 //-------------------------------------------------------------------------------------------------------------
330 // try to close all open frames.
331 // Allow using of any UI ... because Desktop.terminate() was designed as UI functionality in the past.
332 ::sal_Bool bAllowUI = sal_True;
333 ::sal_Bool bFramesClosed = impl_closeFrames(bAllowUI);
334 if ( ! bFramesClosed )
336 impl_sendCancelTerminationEvent(lCalledTerminationListener);
337 return sal_False;
340 //-------------------------------------------------------------------------------------------------------------
341 // Normal listener had no problem ...
342 // all frames was closed ...
343 // now it's time to ask our specialized listener.
344 // They are handled these way because they wish to hinder the office on termination
345 // but they wish also closing of all frames.
347 // Note further:
348 // We shouldn't ask quicklauncher in case it was allowed from outside only.
349 // This is special trick to "ignore existing quick starter" for debug purposes.
351 // Attention:
352 // Order of alled listener is important !
353 // some of them are harmless .-)
354 // But some of them can be dangerous. E.g. it would be dangerous if we close our pipe
355 // and dont terminate in real because another listener throws a veto exception .-)
357 ::sal_Bool bTerminate = sal_False;
361 ( bAskQuickStart ) &&
362 ( xQuickLauncher.is() )
365 xQuickLauncher->queryTermination( aEvent );
366 lCalledTerminationListener.push_back( xQuickLauncher );
369 if ( xSWThreadManager.is() )
371 xSWThreadManager->queryTermination( aEvent );
372 lCalledTerminationListener.push_back( xSWThreadManager );
375 if ( xPipeTerminator.is() )
377 xPipeTerminator->queryTermination( aEvent );
378 lCalledTerminationListener.push_back( xPipeTerminator );
381 if ( xSfxTerminator.is() )
383 xSfxTerminator->queryTermination( aEvent );
384 lCalledTerminationListener.push_back( xSfxTerminator );
387 bTerminate = sal_True;
389 catch(const css::frame::TerminationVetoException&)
391 bTerminate = sal_False;
394 if ( ! bTerminate )
395 impl_sendCancelTerminationEvent(lCalledTerminationListener);
396 else
398 #ifdef ENABLE_ASSERTIONS
399 // "Protect" us against dispose before terminate calls!
400 // see dispose() for further informations.
401 /* SAFE AREA --------------------------------------------------------------------------------------- */
402 WriteGuard aWriteLock( m_aLock );
403 m_bIsTerminated = sal_True;
404 aWriteLock.unlock();
405 /* UNSAFE AREA ------------------------------------------------------------------------------------- */
406 #endif
408 impl_sendNotifyTerminationEvent();
411 ( bAskQuickStart ) &&
412 ( xQuickLauncher.is() )
415 xQuickLauncher->notifyTermination( aEvent );
418 if ( xSWThreadManager.is() )
419 xSWThreadManager->notifyTermination( aEvent );
421 if ( xPipeTerminator.is() )
422 xPipeTerminator->notifyTermination( aEvent );
424 // Must be realy the last listener to be called.
425 // Because it shutdown the whole process asynchronous !
426 if ( xSfxTerminator.is() )
427 xSfxTerminator->notifyTermination( aEvent );
430 return bTerminate;
434 //=============================================================================
435 void SAL_CALL Desktop::addTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener )
436 throw( css::uno::RuntimeException )
438 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
440 css::uno::Reference< css::lang::XServiceInfo > xInfo( xListener, css::uno::UNO_QUERY );
441 if ( xInfo.is() )
443 ::rtl::OUString sImplementationName = xInfo->getImplementationName();
445 // SYCNHRONIZED ->
446 WriteGuard aWriteLock( m_aLock );
448 if( sImplementationName.equals(IMPLEMENTATIONNAME_SFXTERMINATOR) )
450 m_xSfxTerminator = xListener;
451 return;
453 if( sImplementationName.equals(IMPLEMENTATIONNAME_PIPETERMINATOR) )
455 m_xPipeTerminator = xListener;
456 return;
458 if( sImplementationName.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER) )
460 m_xQuickLauncher = xListener;
461 return;
463 if( sImplementationName.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER) )
465 m_xSWThreadManager = xListener;
466 return;
469 aWriteLock.unlock();
470 // <- SYCNHRONIZED
473 // No lock required ... container is threadsafe by itself.
474 m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ), xListener );
477 //=============================================================================
478 void SAL_CALL Desktop::removeTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener )
479 throw( css::uno::RuntimeException )
481 TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
483 css::uno::Reference< css::lang::XServiceInfo > xInfo( xListener, css::uno::UNO_QUERY );
484 if ( xInfo.is() )
486 ::rtl::OUString sImplementationName = xInfo->getImplementationName();
488 // SYCNHRONIZED ->
489 WriteGuard aWriteLock( m_aLock );
491 if( sImplementationName.equals(IMPLEMENTATIONNAME_SFXTERMINATOR) )
493 m_xSfxTerminator.clear();
494 return;
497 if( sImplementationName.equals(IMPLEMENTATIONNAME_PIPETERMINATOR) )
499 m_xPipeTerminator.clear();
500 return;
503 if( sImplementationName.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER) )
505 m_xQuickLauncher.clear();
506 return;
509 if( sImplementationName.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER) )
511 m_xSWThreadManager.clear();
512 return;
515 aWriteLock.unlock();
516 // <- SYCNHRONIZED
519 // No lock required ... container is threadsafe by itself.
520 m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ), xListener );
523 /*-************************************************************************************************************//**
524 @interface XDesktop
525 @short get access to create enumerations of all current components
526 @descr You will be the owner of the returned object and must delete it if you don't use it again.
528 @seealso class TasksAccess
529 @seealso class TasksEnumeration
531 @param -
532 @return A reference to an XEnumerationAccess-object.
534 @onerror We return a null-reference.
535 @threadsafe yes
536 *//*-*************************************************************************************************************/
537 css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL Desktop::getComponents() throw( css::uno::RuntimeException )
539 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
540 // Register transaction and reject wrong calls.
541 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
543 // We use a helper class OComponentAccess to have access on all child components.
544 // Create it on demand and return it as a reference.
545 OComponentAccess* pAccess = new OComponentAccess( this );
546 css::uno::Reference< css::container::XEnumerationAccess > xAccess( static_cast< ::cppu::OWeakObject* >(pAccess), css::uno::UNO_QUERY );
547 return xAccess;
550 /*-************************************************************************************************************//**
551 @interface XDesktop
552 @short return the current active component
553 @descr The most current component is the window, model or the controller of the current active frame.
555 @seealso method getCurrentFrame()
556 @seealso method impl_getFrameComponent()
558 @param -
559 @return A reference to the component.
561 @onerror We return a null-reference.
562 @threadsafe yes
563 *//*-*************************************************************************************************************/
564 css::uno::Reference< css::lang::XComponent > SAL_CALL Desktop::getCurrentComponent() throw( css::uno::RuntimeException )
566 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
567 // Register transaction and reject wrong calls.
568 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
570 // Set return value if method failed.
571 css::uno::Reference< css::lang::XComponent > xComponent;
573 // Get reference to current frame ...
574 // ... get component of this frame ... (It can be the window, the model or the controller.)
575 // ... and return the result.
576 css::uno::Reference< css::frame::XFrame > xCurrentFrame = getCurrentFrame();
577 if( xCurrentFrame.is() == sal_True )
579 xComponent = impl_getFrameComponent( xCurrentFrame );
581 return xComponent;
584 /*-************************************************************************************************************//**
585 @interface XDesktop
586 @short return the current active frame in hierarchy
587 @descr There can be more then one different active pathes in our frame hierarchy. But only one of them
588 could be the most active frame (normal he has the focus).
589 Don't mix it with getActiveFrame()! That will return our current active frame, which must be
590 a direct child of us and should be a part(!) of an active path.
592 @seealso method getActiveFrame()
594 @param -
595 @return A valid reference, if there is an active frame.
596 A null reference , otherwise.
598 @onerror We return a null reference.
599 @threadsafe yes
600 *//*-*************************************************************************************************************/
601 css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::getCurrentFrame() throw( css::uno::RuntimeException )
603 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
604 // Register transaction and reject wrong calls.
605 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
607 // Start search with ouer direct active frame (if it exist!).
608 // Search on his children for other active frames too.
609 // Stop if no one could be found and return last of found ones.
610 css::uno::Reference< css::frame::XFramesSupplier > xLast = css::uno::Reference< css::frame::XFramesSupplier >( getActiveFrame(), css::uno::UNO_QUERY );
611 if( xLast.is() == sal_True )
613 css::uno::Reference< css::frame::XFramesSupplier > xNext = css::uno::Reference< css::frame::XFramesSupplier >( xLast->getActiveFrame(), css::uno::UNO_QUERY );
614 while( xNext.is() == sal_True )
616 xLast = xNext;
617 xNext = css::uno::Reference< css::frame::XFramesSupplier >( xNext->getActiveFrame(), css::uno::UNO_QUERY );
620 return css::uno::Reference< css::frame::XFrame >( xLast, css::uno::UNO_QUERY );
623 /*-************************************************************************************************************//**
624 @interface XComponentLoader
625 @short try to load given URL into a task
626 @descr You can give us some informations about the content, which you will load into a frame.
627 We search or create this target for you, make a type detection of given URL and try to load it.
628 As result of this operation we return the new created component or nothing, if loading failed.
630 @seealso -
632 @param "sURL" , URL, which represant the content
633 @param "sTargetFrameName" , name of target frame or special value like "_self", "_blank" ...
634 @param "nSearchFlags" , optional arguments for frame search, if target isn't a special one
635 @param "lArguments" , optional arguments for loading
636 @return A valid component reference, if loading was successfully.
637 A null reference otherwise.
639 @onerror We return a null reference.
640 @threadsafe yes
641 *//*-*************************************************************************************************************/
642 css::uno::Reference< css::lang::XComponent > SAL_CALL Desktop::loadComponentFromURL( const ::rtl::OUString& sURL ,
643 const ::rtl::OUString& sTargetFrameName,
644 sal_Int32 nSearchFlags ,
645 const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::io::IOException ,
646 css::lang::IllegalArgumentException ,
647 css::uno::RuntimeException )
649 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
650 // Register transaction and reject wrong calls.
651 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
652 RTL_LOGFILE_CONTEXT( aLog, "framework (as96863) ::Desktop::loadComponentFromURL" );
654 ReadGuard aReadLock(m_aLock);
655 css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
656 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xFactory;
657 aReadLock.unlock();
659 RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - Desktop::loadComponentFromURL()" );
660 return LoadEnv::loadComponentFromURL(xThis, xSMGR, sURL, sTargetFrameName, nSearchFlags, lArguments);
663 /*-************************************************************************************************************//**
664 @interface XTasksSupplier
665 @short get access to create enumerations of ouer taskchilds
666 @descr Direct childs of desktop are tasks everytime.
667 Call these method to could create enumerations of it.
669 But; Don't forget - you will be the owner of returned object and must release it!
670 We use a helper class to implement the access interface. They hold a weakreference to us.
671 It can be, that the desktop is dead - but not your tasksaccess-object! Then they will do nothing!
672 You can't create enumerations then.
674 @attention Normaly we don't need any lock here. We don't work on internal member!
676 @seealso class TasksAccess
678 @param -
679 @return A reference to an accessobject, which can create enumerations of ouer childtasks.
681 @onerror A null reference is returned.
682 @threadsafe yes
683 *//*-*************************************************************************************************************/
684 css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL Desktop::getTasks() throw( css::uno::RuntimeException )
686 LOG_WARNING("Desktop::getTasks()", "Use of obsolete interface XTaskSupplier")
687 return NULL;
689 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
691 OTasksAccess* pTasksAccess = new OTasksAccess( this, &m_aChildTaskContainer );
692 css::uno::Reference< css::container::XEnumerationAccess > xAccess( static_cast< ::cppu::OWeakObject* >(pTasksAccess), css::uno::UNO_QUERY );
693 return xAccess;
697 /*-************************************************************************************************************//**
698 @interface XTasksSupplier
699 @short return current active task of ouer direct childs
700 @descr Desktop childs are tasks only ! If we have an active path from desktop
701 as top to any frame on bottom, we must have an active direct child. His reference is returned here.
703 @attention a) Do not confuse it with getCurrentFrame()! The current frame don't must one of ouer direct childs.
704 It can be every frame in subtree and must have the focus (Is the last one of an active path!).
705 b) We don't need any lock here. Our container is threadsafe himself and live, if we live!
707 @seealso method getCurrentFrame()
709 @param -
710 @return A reference to ouer current active taskchild.
712 @onerror A null reference is returned.
713 @threadsafe yes
714 *//*-*************************************************************************************************************/
715 css::uno::Reference< css::frame::XTask > SAL_CALL Desktop::getActiveTask() throw( css::uno::RuntimeException )
718 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
720 return css::uno::Reference< css::frame::XTask >( m_aChildTaskContainer.getActive(), css::uno::UNO_QUERY );
722 LOG_WARNING("Desktop::getActiveTask()", "Use of obsolete interface XTaskSupplier")
723 return NULL;
726 /*-************************************************************************************************************//**
727 @interface XDispatchProvider
728 @short search a dispatcher for given URL
729 @descr We use a helper implementation (class DispatchProvider) to do so.
730 So we don't must implement this algorithm twice!
732 @attention We don't need any lock here. Our helper is threadsafe himself and live, if we live!
734 @seealso class DispatchProvider
736 @param "aURL" , URL to dispatch
737 @param "sTargetFrameName" , name of target frame, who should dispatch these URL
738 @param "nSearchFlags" , flags to regulate the search
739 @param "lQueries" , list of queryDispatch() calls!
740 @return A reference or list of founded dispatch objects for these URL.
742 @onerror A null reference is returned.
743 @threadsafe yes
744 *//*-*************************************************************************************************************/
745 css::uno::Reference< css::frame::XDispatch > SAL_CALL Desktop::queryDispatch( const css::util::URL& aURL ,
746 const ::rtl::OUString& sTargetFrameName ,
747 sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
749 const char UNO_PROTOCOL[] = ".uno:";
751 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
752 // Register transaction and reject wrong calls.
753 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
755 // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
756 // in our hash map. All other protocols are stored with the protocol part.
757 String aCommand( aURL.Main );
758 if ( aURL.Protocol.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL, sizeof( UNO_PROTOCOL )-1 ))
759 aCommand = aURL.Path;
761 // Make hash_map lookup if the current URL is in the disabled list
762 if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
763 return css::uno::Reference< css::frame::XDispatch >();
764 else
766 // We use a helper to support these interface and an interceptor mechanism.
767 // Our helper is threadsafe by himself!
768 return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
772 //*****************************************************************************************************************
773 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 )
775 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
776 // Register transaction and reject wrong calls.
777 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
779 return m_xDispatchHelper->queryDispatches( lQueries );
782 /*-************************************************************************************************************//**
783 @interface XDipsatchProviderInterception
784 @short supports registration/deregistration of interception objects, which
785 are interested on special dispatches.
787 @descr Its realy provided by an internal helper, which is used inside the dispatch api too.
788 @param xInterceptor
789 the interceptor object, which wish to be (de)registered.
791 @threadsafe yes
792 *//*-*************************************************************************************************************/
793 void SAL_CALL Desktop::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
794 throw( css::uno::RuntimeException)
796 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
798 css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
799 xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
802 //*****************************************************************************************************************
803 void SAL_CALL Desktop::releaseDispatchProviderInterceptor ( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
804 throw( css::uno::RuntimeException)
806 TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
808 css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
809 xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
812 /*-************************************************************************************************************//**
813 @interface XFramesSupplier
814 @short return access to append or remove childs on desktop
815 @descr We don't implement these interface directly. We use a helper class to do this.
816 If you wish to add or delete childs to/from the container, call these method to get
817 a reference to the helper.
819 @attention Helper is threadsafe himself. So we don't need any lock here.
821 @seealso class OFrames
823 @param -
824 @return A reference to the helper.
826 @onerror A null reference is returned.
827 @threadsafe yes
828 *//*-*************************************************************************************************************/
829 css::uno::Reference< css::frame::XFrames > SAL_CALL Desktop::getFrames() throw( css::uno::RuntimeException )
831 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
832 // Register transaction and reject wrong calls.
833 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
835 return m_xFramesHelper;
838 /*-************************************************************************************************************//**
839 @interface XFramesSupplier
840 @short set/get the current active child frame
841 @descr It must be a task. Direct childs of desktop are tasks only! No frames are accepted.
842 We don't save this information directly in this class. We use ouer container-helper
843 to do that.
845 @attention Helper is threadsafe himself. So we don't need any lock here.
847 @seealso class OFrameContainer
849 @param "xFrame", new active frame (must be valid!)
850 @return A reference to ouer current active childtask, if anyone exist.
852 @onerror A null reference is returned.
853 @threadsafe yes
854 *//*-*************************************************************************************************************/
855 void SAL_CALL Desktop::setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException )
857 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
858 // Register transaction and reject wrong calls.
859 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
861 // Get old active frame first.
862 // If nothing will change - do nothing!
863 // Otherwise set new active frame ...
864 // and deactivate last frame.
865 // It's neccessary for our FrameActionEvent listener on a frame!
866 css::uno::Reference< css::frame::XFrame > xLastActiveChild = m_aChildTaskContainer.getActive();
867 if( xLastActiveChild != xFrame )
869 m_aChildTaskContainer.setActive( xFrame );
870 if( xLastActiveChild.is() == sal_True )
872 xLastActiveChild->deactivate();
877 //*****************************************************************************************************************
878 css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::getActiveFrame() throw( css::uno::RuntimeException )
880 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
881 // Register transaction and reject wrong calls.
882 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
884 return m_aChildTaskContainer.getActive();
887 /*-************************************************************************************************************//**
888 @interface XFrame
889 @short non implemented methods!
890 @descr Some method make no sense for our desktop! He has no window or parent or ...
891 So we should implement it empty and warn programmer, if he use it!
893 @seealso -
895 @param -
896 @return -
898 @onerror -
899 @threadsafe -
900 *//*-*************************************************************************************************************/
901 void SAL_CALL Desktop::initialize( const css::uno::Reference< css::awt::XWindow >& ) throw( css::uno::RuntimeException )
905 //*****************************************************************************************************************
906 css::uno::Reference< css::awt::XWindow > SAL_CALL Desktop::getContainerWindow() throw( css::uno::RuntimeException )
908 return css::uno::Reference< css::awt::XWindow >();
911 //*****************************************************************************************************************
912 void SAL_CALL Desktop::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& /*xCreator*/ ) throw( css::uno::RuntimeException )
916 //*****************************************************************************************************************
917 css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Desktop::getCreator() throw( css::uno::RuntimeException )
919 return css::uno::Reference< css::frame::XFramesSupplier >();
922 //*****************************************************************************************************************
923 ::rtl::OUString SAL_CALL Desktop::getName() throw( css::uno::RuntimeException )
925 /* SAFE { */
926 ReadGuard aReadLock( m_aLock );
927 return m_sName;
928 /* } SAFE */
931 //*****************************************************************************************************************
932 void SAL_CALL Desktop::setName( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException )
934 /* SAFE { */
935 WriteGuard aWriteLock( m_aLock );
936 m_sName = sName;
937 aWriteLock.unlock();
938 /* } SAFE */
941 //*****************************************************************************************************************
942 sal_Bool SAL_CALL Desktop::isTop() throw( css::uno::RuntimeException )
944 return sal_True;
947 //*****************************************************************************************************************
948 void SAL_CALL Desktop::activate() throw( css::uno::RuntimeException )
950 // Desktop is activae always ... but sometimes our frames try to activate
951 // the complete path from bottom to top ... And our desktop is the topest frame :-(
952 // So - please don't show any assertions here. Do nothing!
955 //*****************************************************************************************************************
956 void SAL_CALL Desktop::deactivate() throw( css::uno::RuntimeException )
958 // Desktop is activae always ... but sometimes our frames try to deactivate
959 // the complete path from bottom to top ... And our desktop is the topest frame :-(
960 // So - please don't show any assertions here. Do nothing!
963 //*****************************************************************************************************************
964 sal_Bool SAL_CALL Desktop::isActive() throw( css::uno::RuntimeException )
966 return sal_True;
969 //*****************************************************************************************************************
970 sal_Bool SAL_CALL Desktop::setComponent( const css::uno::Reference< css::awt::XWindow >& /*xComponentWindow*/ ,
971 const css::uno::Reference< css::frame::XController >& /*xController*/ ) throw( css::uno::RuntimeException )
973 return sal_False;
976 //*****************************************************************************************************************
977 css::uno::Reference< css::awt::XWindow > SAL_CALL Desktop::getComponentWindow() throw( css::uno::RuntimeException )
979 return css::uno::Reference< css::awt::XWindow >();
982 //*****************************************************************************************************************
983 css::uno::Reference< css::frame::XController > SAL_CALL Desktop::getController() throw( css::uno::RuntimeException )
985 return css::uno::Reference< css::frame::XController >();
988 //*****************************************************************************************************************
989 void SAL_CALL Desktop::contextChanged() throw( css::uno::RuntimeException )
993 //*****************************************************************************************************************
994 void SAL_CALL Desktop::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& ) throw( css::uno::RuntimeException )
998 //*****************************************************************************************************************
999 // css::frame::XFrame
1000 //*****************************************************************************************************************
1001 void SAL_CALL Desktop::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& ) throw( css::uno::RuntimeException )
1005 /*-************************************************************************************************************//**
1006 @interface XFrame
1007 @short try to find a frame with special parameters
1008 @descr This method searches for a frame with the specified name.
1009 Frames may contain other frames (e.g. a frameset) and may
1010 be contained in other frames. This hierarchie ist searched by
1011 this method.
1012 First some special names are taken into account, i.e. "",
1013 "_self", "_top", "_parent" etc. The FrameSearchFlags are ignored
1014 when comparing these names with aTargetFrameName, further steps are
1015 controlled by the FrameSearchFlags. If allowed, the name of the frame
1016 itself is compared with the desired one, then ( again if allowed )
1017 the method findFrame is called for all children of the frame.
1018 If no Frame with the given name is found until the top frames container,
1019 a new top Frame is created, if this is allowed by a special
1020 FrameSearchFlag. The new Frame also gets the desired name.
1021 We use a helper to get right search direction and react in a right manner.
1023 @seealso class TargetFinder
1025 @param "sTargetFrameName" , name of searched frame
1026 @param "nSearchFlags" , flags to regulate search
1027 @return A reference to an existing frame in hierarchy, if it exist.
1029 @onerror A null reference is returned.
1030 @threadsafe yes
1031 *//*-*************************************************************************************************************/
1032 css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::findFrame( const ::rtl::OUString& sTargetFrameName ,
1033 sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
1035 css::uno::Reference< css::frame::XFrame > xTarget;
1037 //-----------------------------------------------------------------------------------------------------
1038 // 0) Ignore wrong parameter!
1039 // We doesn't support search for following special targets.
1040 // If we reject this requests - we mustnt check for such names
1041 // in following code again and again. If we do not so -wrong
1042 // search results can occure!
1043 //-----------------------------------------------------------------------------------------------------
1044 if (
1045 (sTargetFrameName==SPECIALTARGET_DEFAULT ) || // valid for dispatches - not for findFrame()!
1046 (sTargetFrameName==SPECIALTARGET_MENUBAR ) || // valid for dispatches - not for findFrame()!
1047 (sTargetFrameName==SPECIALTARGET_HELPAGENT) || // valid for dispatches - not for findFrame()!
1048 (sTargetFrameName==SPECIALTARGET_PARENT ) || // we have no parent by definition
1049 (sTargetFrameName==SPECIALTARGET_BEAMER ) // beamer frames are allowed as child of tasks only -
1050 // and they exist more then ones. We have no idea which our sub tasks is the right one
1053 return NULL;
1056 //-----------------------------------------------------------------------------------------------------
1057 // I) check for special defined targets first which must be handled exclusive.
1058 // force using of "if() else if() ..."
1059 //-----------------------------------------------------------------------------------------------------
1061 // get threadsafe some neccessary member which are neccessary for following functionality
1062 /* SAFE { */
1063 ReadGuard aReadLock( m_aLock );
1064 css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
1065 aReadLock.unlock();
1066 /* } SAFE */
1068 //-----------------------------------------------------------------------------------------------------
1069 // I.I) "_blank"
1070 // create a new task as child of this desktop instance
1071 // Note: Used helper TaskCreator use us automaticly ...
1072 //-----------------------------------------------------------------------------------------------------
1073 if ( sTargetFrameName==SPECIALTARGET_BLANK )
1075 TaskCreator aCreator(xFactory);
1076 xTarget = aCreator.createTask(sTargetFrameName,sal_False);
1079 //-----------------------------------------------------------------------------------------------------
1080 // I.II) "_top"
1081 // We are top by definition
1082 //-----------------------------------------------------------------------------------------------------
1083 else
1084 if ( sTargetFrameName==SPECIALTARGET_TOP )
1086 xTarget = this;
1089 //-----------------------------------------------------------------------------------------------------
1090 // I.III) "_self", ""
1091 // This mean this "frame" in every case.
1092 //-----------------------------------------------------------------------------------------------------
1093 else
1094 if (
1095 ( sTargetFrameName==SPECIALTARGET_SELF ) ||
1096 ( sTargetFrameName.getLength()<1 )
1099 xTarget = this;
1102 else
1104 //-------------------------------------------------------------------------------------------------
1105 // II) otherwhise use optional given search flags
1106 // force using of combinations of such flags. means no "else" part of use if() statements.
1107 // But we ust break further searches if target was already found.
1108 // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
1109 // TASK and CREATE are handled special.
1110 // But note: Such flags are not valid for the desktop - especialy SIBLINGS or PARENT.
1111 //-------------------------------------------------------------------------------------------------
1113 // get threadsafe some neccessary member which are neccessary for following functionality
1114 /* SAFE { */
1115 aReadLock.lock();
1116 ::rtl::OUString sOwnName = m_sName;
1117 aReadLock.unlock();
1118 /* } SAFE */
1120 //-------------------------------------------------------------------------------------------------
1121 // II.I) SELF
1122 // Check for right name. If it's the searched one return ourself - otherwhise
1123 // ignore this flag.
1124 //-------------------------------------------------------------------------------------------------
1125 if (
1126 (nSearchFlags & css::frame::FrameSearchFlag::SELF) &&
1127 (sOwnName == sTargetFrameName )
1130 xTarget = this;
1133 //-------------------------------------------------------------------------------------------------
1134 // II.II) TASKS
1135 // This is a special flag. Normaly it regulate search inside tasks and forbid access to parent trees.
1136 // But the desktop exists outside such task trees. They are our sub trees. So the desktop implement
1137 // a special feature: We use it to start search on our direct childrens only. That means we supress
1138 // search on ALL child frames. May that can be usefull to get access on opened document tasks
1139 // only without filter out all non realy required sub frames ...
1140 // Used helper method on our container doesn't create any frame - its a search only.
1141 //-------------------------------------------------------------------------------------------------
1142 if (
1143 ( ! xTarget.is() ) &&
1144 (nSearchFlags & css::frame::FrameSearchFlag::TASKS)
1147 xTarget = m_aChildTaskContainer.searchOnDirectChildrens(sTargetFrameName);
1150 //-------------------------------------------------------------------------------------------------
1151 // II.III) CHILDREN
1152 // Search on all children for the given target name.
1153 // An empty name value can't occure here - because it must be already handled as "_self"
1154 // before. Used helper function of container doesn't create any frame.
1155 // It makes a deep search only.
1156 //-------------------------------------------------------------------------------------------------
1157 if (
1158 ( ! xTarget.is() ) &&
1159 (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
1162 xTarget = m_aChildTaskContainer.searchOnAllChildrens(sTargetFrameName);
1165 //-------------------------------------------------------------------------------------------------
1166 // II.IV) CREATE
1167 // If we haven't found any valid target frame by using normal flags - but user allowed us to create
1168 // a new one ... we should do that. Used TaskCreator use us automaticly as parent!
1169 //-------------------------------------------------------------------------------------------------
1170 if (
1171 ( ! xTarget.is() ) &&
1172 (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
1175 TaskCreator aCreator(xFactory);
1176 xTarget = aCreator.createTask(sTargetFrameName,sal_False);
1180 return xTarget;
1183 //=============================================================================
1184 void SAL_CALL Desktop::dispose()
1185 throw( css::uno::RuntimeException )
1187 // Safe impossible cases
1188 // It's an programming error if dispose is called before terminate!
1189 LOG_ASSERT2( m_bIsTerminated==sal_False, "Desktop::dispose()", "It's not allowed to dispose the desktop before terminate() is called!" )
1191 SYNCHRONIZED_START
1192 WriteGuard aWriteLock( m_aLock );
1194 // Look for multiple calls of this method!
1195 // If somewhere call dispose() twice - he will be stopped here realy!!!
1196 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1198 // Now - we are alone and its the first call of this method ...
1199 // otherwise call before had thrown a DisposedException / hopefully .-)
1200 // But we dont use the transaction object created before ... we reset it immediatly ...
1201 // two lines of code ... for what ?
1202 // The answer: We wished to synchronize concurrent dispose() calls -> OK
1203 // But next line will wait for all currently running transaction (even if they
1204 // are running within the same thread!) So we would block ourself there if aTransaction
1205 // will stay registered .-)
1206 aTransaction.stop();
1208 // Disable this instance for further work.
1209 // This will wait for all current running transactions ...
1210 // and reject all new incoming requests!
1211 m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
1213 aWriteLock.unlock();
1214 SYNCHRONIZED_END
1216 // Following lines of code can be called outside a synchronized block ...
1217 // Because our transaction manager will block all new requests to this object.
1218 // So nobody can use us any longer.
1219 // Exception: Only removing of listener will work ... and this code cant be dangerous.
1221 // First we has to kill all listener connections.
1222 // They might rely on our member and can hinder us on releasing them.
1223 css::uno::Reference< css::uno::XInterface > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1224 css::lang::EventObject aEvent( xThis );
1225 m_aListenerContainer.disposeAndClear( aEvent );
1227 // Clear our child task container and forget all task references hardly.
1228 // Normaly all open document was already closed by our terminate() function before ...
1229 // New opened frames will have a problem now .-)
1230 m_aChildTaskContainer.clear();
1232 // Dispose our helper too.
1233 css::uno::Reference< css::lang::XEventListener > xFramesHelper( m_xFramesHelper, css::uno::UNO_QUERY );
1234 if( xFramesHelper.is() )
1235 xFramesHelper->disposing( aEvent );
1237 // At least clean up other member references.
1238 m_xDispatchHelper.clear();
1239 m_xFramesHelper.clear();
1240 m_xLastFrame.clear();
1241 m_xFactory.clear();
1243 m_xPipeTerminator.clear();
1244 m_xQuickLauncher.clear();
1245 m_xSWThreadManager.clear();
1246 m_xSfxTerminator.clear();
1248 // From this point nothing will work further on this object ...
1249 // excepting our dtor() .-)
1250 m_aTransactionManager.setWorkingMode( E_CLOSE );
1253 /*-************************************************************************************************************//**
1254 @interface XComponent
1255 @short add/remove listener for dispose events
1256 @descr Add an event listener to this object, if you whish to get informations
1257 about our dieing!
1258 You must releas ethis listener reference during your own disposing() method.
1260 @attention Our container is threadsafe himeslf. So we doesn't need any lock here.
1262 @seealso -
1264 @param "xListener", reference to valid listener. We don't accept invalid values!
1265 @return -
1267 @onerror -
1268 @threadsafe yes
1269 *//*-*************************************************************************************************************/
1270 void SAL_CALL Desktop::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
1272 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1273 // Safe impossible cases
1274 // Method not defined for all incoming parameter.
1275 LOG_ASSERT2( implcp_addEventListener( xListener ), "Desktop::addEventListener()", "Invalid parameter detected!" )
1276 // Register transaction and reject wrong calls.
1277 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1279 m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >*) NULL ), xListener );
1282 //*****************************************************************************************************************
1283 void SAL_CALL Desktop::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
1285 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1286 // Safe impossible cases
1287 // Method not defined for all incoming parameter.
1288 LOG_ASSERT2( implcp_removeEventListener( xListener ), "Desktop::removeEventListener()", "Invalid parameter detected!" )
1289 // Register transaction and reject wrong calls.
1290 TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1292 m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >*) NULL ), xListener );
1295 /*-************************************************************************************************************//**
1296 @interface XDispatchResultListener
1297 @short callback for dispatches
1298 @descr To support our method "loadComponentFromURL()" we are listener on temp. created dispatcher.
1299 They call us back in this method "statusChanged()". As source of given state event, they give us a
1300 reference to the target frame, in which dispatch was loaded! So we can use it to return his component
1301 to caller! If no target exist ... ??!!
1303 @seealso method loadComponentFromURL()
1305 @param "aEvent", state event which (hopefully) valid informations
1306 @return -
1308 @onerror -
1309 @threadsafe yes
1310 *//*-*************************************************************************************************************/
1311 void SAL_CALL Desktop::dispatchFinished( const css::frame::DispatchResultEvent& aEvent ) throw( css::uno::RuntimeException )
1313 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1314 // Register transaction and reject wrong calls.
1315 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1317 /* SAFE AREA ------------------------------------------------------------------------------------------- */
1318 WriteGuard aWriteLock( m_aLock );
1319 if( m_eLoadState != E_INTERACTION )
1321 m_xLastFrame = css::uno::Reference< css::frame::XFrame >();
1322 m_eLoadState = E_FAILED ;
1323 if( aEvent.State == css::frame::DispatchResultState::SUCCESS )
1325 css::uno::Reference < css::frame::XFrame > xFrame;
1326 if ( aEvent.Result >>= m_xLastFrame )
1327 m_eLoadState = E_SUCCESSFUL;
1330 /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
1333 /*-************************************************************************************************************//**
1334 @interface XEventListener
1335 @short not implemented!
1336 @descr We are a status listener ... and so we must be an event listener too ... But we doesn't need it realy!
1337 We are a temp. listener only and our lifetime isn't smaller then of our temp. used dispatcher.
1339 @seealso method loadComponentFromURL()
1341 @param -
1342 @return -
1344 @onerror -
1345 @threadsafe -
1346 *//*-*************************************************************************************************************/
1347 void SAL_CALL Desktop::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
1349 LOG_ERROR( "Desktop::disposing()", "Algorithm error! Normaly desktop is temp. listener ... not all the time. So this method shouldn't be called." )
1352 /*-************************************************************************************************************//**
1353 @interface XInteractionHandler
1354 @short callback for loadComponentFromURL for detected exceptions during load proccess
1355 @descr In this case we must cancel loading and throw these detected exception again as result
1356 of our own called method.
1358 @attention a)
1359 Normal loop in loadComponentFromURL() breaks on setted member m_eLoadState during callback statusChanged().
1360 But these interaction feature implements second way to do so! So we must look on different callbacks
1361 for same operation ... and live with it.
1363 Search for given continuations too. If any XInteractionAbort exist ... use it to abort further operations
1364 for currently running operation!
1366 @seealso method loadComponentFromURL()
1367 @seealso member m_eLoadState
1369 @param "xRequest", request for interaction - normal a wrapped target exception from bottom services
1370 @return -
1372 @onerror -
1373 @threadsafe yes
1374 *//*-*************************************************************************************************************/
1375 void SAL_CALL Desktop::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest ) throw( css::uno::RuntimeException )
1377 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1378 // Register transaction and reject wrong calls.
1379 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1381 // Don't check incoming request!
1382 // If somewhere starts interaction without right parameter - he maked something wrong.
1383 // loadComponentFromURL() waits for thjese event - otherwise it yield for ever!
1385 // get packed request and work on it first
1386 // Attention: Don't set it on internal member BEFORE interaction is finished - because
1387 // "loadComponentFromURL()" yield tills this member is changed. If we do it before
1388 // interaction finish we can't guarantee right functionality. May be we cancel load process to erliear ...
1389 css::uno::Any aRequest = xRequest->getRequest();
1391 // extract continuations from request
1392 css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
1393 css::uno::Reference< css::task::XInteractionAbort > xAbort ;
1394 css::uno::Reference< css::task::XInteractionApprove > xApprove ;
1395 css::uno::Reference< css::document::XInteractionFilterSelect > xFilterSelect ;
1396 sal_Bool bAbort = sal_False;
1398 sal_Int32 nCount=lContinuations.getLength();
1399 for( sal_Int32 nStep=0; nStep<nCount; ++nStep )
1401 if( ! xAbort.is() )
1402 xAbort = css::uno::Reference< css::task::XInteractionAbort >( lContinuations[nStep], css::uno::UNO_QUERY );
1404 if( ! xApprove.is() )
1405 xApprove = css::uno::Reference< css::task::XInteractionApprove >( lContinuations[nStep], css::uno::UNO_QUERY );
1407 if( ! xFilterSelect.is() )
1408 xFilterSelect = css::uno::Reference< css::document::XInteractionFilterSelect >( lContinuations[nStep], css::uno::UNO_QUERY );
1411 // differ between abortable interactions (error, unknown filter ...)
1412 // and other ones (ambigous but not unknown filter ...)
1413 css::task::ErrorCodeRequest aErrorCodeRequest ;
1414 css::document::AmbigousFilterRequest aAmbigousFilterRequest;
1415 if( aRequest >>= aAmbigousFilterRequest )
1417 if( xFilterSelect.is() )
1419 xFilterSelect->setFilter( aAmbigousFilterRequest.SelectedFilter ); // user selected filter wins!
1420 xFilterSelect->select();
1423 else
1424 if( aRequest >>= aErrorCodeRequest )
1426 sal_Bool bWarning = ((aErrorCodeRequest.ErrCode & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
1427 if (xApprove.is() && bWarning)
1428 xApprove->select();
1429 else
1430 if (xAbort.is())
1432 xAbort->select();
1433 bAbort = sal_True;
1436 else
1437 if( xAbort.is() )
1439 xAbort->select();
1440 bAbort = sal_True;
1443 /* SAFE AREA ------------------------------------------------------------------------------------------- */
1444 // Ok now it's time to break yield loop of loadComponentFromURL().
1445 // But only for realy aborted requests!
1446 // For example warnings will be approved and we wait for any success story ...
1447 if (bAbort)
1449 WriteGuard aWriteLock( m_aLock );
1450 m_eLoadState = E_INTERACTION;
1451 m_aInteractionRequest = aRequest ;
1452 aWriteLock.unlock();
1454 /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
1457 //-----------------------------------------------------------------------------
1458 ::sal_Int32 SAL_CALL Desktop::leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent )
1459 throw (css::lang::IllegalArgumentException,
1460 css::uno::RuntimeException )
1462 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1463 return m_xTitleNumberGenerator->leaseNumber (xComponent);
1466 //-----------------------------------------------------------------------------
1467 void SAL_CALL Desktop::releaseNumber( ::sal_Int32 nNumber )
1468 throw (css::lang::IllegalArgumentException,
1469 css::uno::RuntimeException )
1471 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1472 m_xTitleNumberGenerator->releaseNumber (nNumber);
1475 //-----------------------------------------------------------------------------
1476 void SAL_CALL Desktop::releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent )
1477 throw (css::lang::IllegalArgumentException,
1478 css::uno::RuntimeException )
1480 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1481 m_xTitleNumberGenerator->releaseNumberForComponent (xComponent);
1484 //-----------------------------------------------------------------------------
1485 ::rtl::OUString SAL_CALL Desktop::getUntitledPrefix()
1486 throw (css::uno::RuntimeException)
1488 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1489 return m_xTitleNumberGenerator->getUntitledPrefix ();
1492 /*-************************************************************************************************************//**
1493 @short try to convert a property value
1494 @descr This method is called from helperclass "OPropertySetHelper".
1495 Don't use this directly!
1496 You must try to convert the value of given DESKTOP_PROPHANDLE and
1497 return results of this operation. This will be used to ask vetoable
1498 listener. If no listener has a veto, we will change value realy!
1499 ( in method setFastPropertyValue_NoBroadcast(...) )
1501 @attention Methods of OPropertySethelper are safed by using our shared osl mutex! (see ctor!)
1502 So we must use different locks to make our implementation threadsafe.
1504 @seealso class OPropertySetHelper
1505 @seealso method setFastPropertyValue_NoBroadcast()
1507 @param "aConvertedValue" new converted value of property
1508 @param "aOldValue" old value of property
1509 @param "nHandle" handle of property
1510 @param "aValue" new value of property
1511 @return sal_True if value will be changed, sal_FALSE otherway
1513 @onerror IllegalArgumentException, if you call this with an invalid argument
1514 @threadsafe yes
1515 *//*-*************************************************************************************************************/
1516 sal_Bool SAL_CALL Desktop::convertFastPropertyValue( css::uno::Any& aConvertedValue ,
1517 css::uno::Any& aOldValue ,
1518 sal_Int32 nHandle ,
1519 const css::uno::Any& aValue ) throw( css::lang::IllegalArgumentException )
1521 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1522 // Register transaction and reject wrong calls.
1523 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1525 // Initialize state with FALSE !!!
1526 // (Handle can be invalid)
1527 sal_Bool bReturn = sal_False;
1529 switch( nHandle )
1531 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO:
1532 bReturn = PropHelper::willPropertyBeChanged(
1533 css::uno::makeAny(m_bSuspendQuickstartVeto),
1534 aValue,
1535 aOldValue,
1536 aConvertedValue);
1537 break;
1538 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
1539 bReturn = PropHelper::willPropertyBeChanged(
1540 css::uno::makeAny(m_xDispatchRecorderSupplier),
1541 aValue,
1542 aOldValue,
1543 aConvertedValue);
1544 break;
1545 case DESKTOP_PROPHANDLE_TITLE :
1546 bReturn = PropHelper::willPropertyBeChanged(
1547 css::uno::makeAny(m_sTitle),
1548 aValue,
1549 aOldValue,
1550 aConvertedValue);
1551 break;
1554 // Return state of operation.
1555 return bReturn ;
1558 /*-************************************************************************************************************//**
1559 @short set value of a transient property
1560 @descr This method is calling from helperclass "OPropertySetHelper".
1561 Don't use this directly!
1562 Handle and value are valid everyway! You must set the new value only.
1563 After this, baseclass send messages to all listener automaticly.
1565 @seealso class OPropertySetHelper
1567 @param "nHandle" handle of property to change
1568 @param "aValue" new value of property
1569 @return -
1571 @onerror An exception is thrown.
1572 @threadsafe yes
1573 *//*-*************************************************************************************************************/
1574 void SAL_CALL Desktop::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle ,
1575 const css::uno::Any& aValue ) throw( css::uno::Exception )
1577 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1578 // Register transaction and reject wrong calls.
1579 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1581 switch( nHandle )
1583 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO: aValue >>= m_bSuspendQuickstartVeto;
1584 break;
1585 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER: aValue >>= m_xDispatchRecorderSupplier;
1586 break;
1587 case DESKTOP_PROPHANDLE_TITLE: aValue >>= m_sTitle;
1588 break;
1592 /*-************************************************************************************************************//**
1593 @short get value of a transient property
1594 @descr This method is calling from helperclass "OPropertySetHelper".
1595 Don't use this directly!
1597 @attention We don't need any mutex or lock here ... We use threadsafe container or methods here only!
1599 @seealso class OPropertySetHelper
1601 @param "nHandle" handle of property to change
1602 @param "aValue" current value of property
1603 @return -
1605 @onerror -
1606 @threadsafe yes
1607 *//*-*************************************************************************************************************/
1608 void SAL_CALL Desktop::getFastPropertyValue( css::uno::Any& aValue ,
1609 sal_Int32 nHandle ) const
1611 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1612 // Register transaction and reject wrong calls.
1613 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1615 switch( nHandle )
1617 case DESKTOP_PROPHANDLE_ACTIVEFRAME : aValue <<= m_aChildTaskContainer.getActive();
1618 break;
1619 case DESKTOP_PROPHANDLE_ISPLUGGED : aValue <<= sal_False;
1620 break;
1621 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO: aValue <<= m_bSuspendQuickstartVeto;
1622 break;
1623 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER: aValue <<= m_xDispatchRecorderSupplier;
1624 break;
1625 case DESKTOP_PROPHANDLE_TITLE: aValue <<= m_sTitle;
1626 break;
1630 /*-************************************************************************************************************//**
1631 @short return structure and information about transient properties
1632 @descr This method is calling from helperclass "OPropertySetHelper".
1633 Don't use this directly!
1635 @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
1636 Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
1637 So we could have two different mutex/lock mechanism at the same object.
1639 @seealso class OPropertySetHelper
1641 @param -
1642 @return structure with property-informations
1644 @onerror -
1645 @threadsafe yes
1646 *//*-*************************************************************************************************************/
1647 ::cppu::IPropertyArrayHelper& SAL_CALL Desktop::getInfoHelper()
1649 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1650 // Register transaction and reject wrong calls.
1651 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1653 // Optimize this method !
1654 // We initialize a static variable only one time. And we don't must use a mutex at every call!
1655 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
1656 static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
1658 if( pInfoHelper == NULL )
1660 // Ready for multithreading
1661 ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
1662 // Control this pointer again, another instance can be faster then these!
1663 if( pInfoHelper == NULL )
1665 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
1666 // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
1667 // "sal_True" say: Table is sorted by name.
1668 static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
1669 pInfoHelper = &aInfoHelper;
1673 return(*pInfoHelper);
1676 /*-************************************************************************************************************//**
1677 @short return propertysetinfo
1678 @descr You can call this method to get information about transient properties
1679 of this object.
1681 @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
1682 Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
1683 So we could have two different mutex/lock mechanism at the same object.
1685 @seealso class OPropertySetHelper
1686 @seealso interface XPropertySet
1687 @seealso interface XMultiPropertySet
1689 @param -
1690 @return reference to object with information [XPropertySetInfo]
1692 @onerror -
1693 @threadsafe yes
1694 *//*-*************************************************************************************************************/
1695 css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL Desktop::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException)
1697 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1698 // Register transaction and reject wrong calls.
1699 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1701 // Optimize this method !
1702 // We initialize a static variable only one time. And we don't must use a mutex at every call!
1703 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
1704 static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL;
1706 if( pInfo == NULL )
1708 // Ready for multithreading
1709 ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
1710 // Control this pointer again, another instance can be faster then these!
1711 if( pInfo == NULL )
1713 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
1714 // (Use method "getInfoHelper()".)
1715 static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
1716 pInfo = &xInfo;
1720 return (*pInfo);
1723 /*-************************************************************************************************************//**
1724 @short return current component of current frame
1725 @descr The desktop himself has no component. But every frame in subtree.
1726 If somewhere call getCurrentComponent() at this class, we try to find the right frame and
1727 then we try to become his component. It can be a VCL-component, the model or the controller
1728 of founded frame.
1730 @attention We don't work on internal member ... so we doesn't need any lock here.
1732 @seealso method getCurrentComponent();
1734 @param "xFrame", reference to valid frame in hierarchy. Method is not defined for invalid values.
1735 But we don't check these. Its an IMPL-method and caller must use it right!
1736 @return A reference to found component.
1738 @onerror A null reference is returned.
1739 @threadsafe yes
1740 *//*-*************************************************************************************************************/
1741 css::uno::Reference< css::lang::XComponent > Desktop::impl_getFrameComponent( const css::uno::Reference< css::frame::XFrame >& xFrame ) const
1743 /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1744 // Register transaction and reject wrong calls.
1745 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1747 // Set default return value, if method failed.
1748 css::uno::Reference< css::lang::XComponent > xComponent;
1749 // Does no controller exists?
1750 css::uno::Reference< css::frame::XController > xController = xFrame->getController();
1751 if( xController.is() == sal_False )
1753 // Controller not exist - use the VCL-component.
1754 xComponent = css::uno::Reference< css::lang::XComponent >( xFrame->getComponentWindow(), css::uno::UNO_QUERY );
1756 else
1758 // Does no model exists?
1759 css::uno::Reference< css::frame::XModel > xModel( xController->getModel(), css::uno::UNO_QUERY );
1760 if( xModel.is() == sal_True )
1762 // Model exist - use the model as component.
1763 xComponent = css::uno::Reference< css::lang::XComponent >( xModel, css::uno::UNO_QUERY );
1765 else
1767 // Model not exist - use the controller as component.
1768 xComponent = css::uno::Reference< css::lang::XComponent >( xController, css::uno::UNO_QUERY );
1772 return xComponent;
1775 /*-************************************************************************************************************//**
1776 @short create table with information about properties
1777 @descr We use a helper class to support properties. These class need some information about this.
1778 These method create a new static description table with name, type, r/w-flags and so on ...
1780 @seealso class OPropertySetHelper
1781 @seealso method getInfoHelper()
1783 @param -
1784 @return Static table with information about properties.
1786 @onerror -
1787 @threadsafe yes
1788 *//*-*************************************************************************************************************/
1789 const css::uno::Sequence< css::beans::Property > Desktop::impl_getStaticPropertyDescriptor()
1791 // Create a new static property array to initialize sequence!
1792 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
1793 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
1794 // It's necessary for methods of OPropertySetHelper.
1795 // ATTENTION:
1796 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
1798 static const css::beans::Property pProperties[] =
1800 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 ),
1801 css::beans::Property( DESKTOP_PROPNAME_DISPATCHRECORDERSUPPLIER , DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER, ::getCppuType((const css::uno::Reference< css::frame::XDispatchRecorderSupplier >*)NULL), css::beans::PropertyAttribute::TRANSIENT ),
1802 css::beans::Property( DESKTOP_PROPNAME_ISPLUGGED , DESKTOP_PROPHANDLE_ISPLUGGED , ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
1803 css::beans::Property( DESKTOP_PROPNAME_SUSPENDQUICKSTARTVETO , DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO , ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT ),
1804 css::beans::Property( DESKTOP_PROPNAME_TITLE , DESKTOP_PROPHANDLE_TITLE , ::getCppuType((const ::rtl::OUString*)NULL) , css::beans::PropertyAttribute::TRANSIENT ),
1806 // Use it to initialize sequence!
1807 static const css::uno::Sequence< css::beans::Property > lPropertyDescriptor( pProperties, DESKTOP_PROPCOUNT );
1808 // Return static "PropertyDescriptor"
1809 return lPropertyDescriptor;
1812 //=============================================================================
1813 void Desktop::impl_sendQueryTerminationEvent(Desktop::TTerminateListenerList& lCalledListener,
1814 ::sal_Bool& bVeto )
1816 bVeto = sal_False;
1818 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1820 ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ) );
1821 if ( ! pContainer )
1822 return;
1824 css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
1826 ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
1827 while ( aIterator.hasMoreElements() )
1831 css::uno::Reference< css::frame::XTerminateListener > xListener(aIterator.next(), css::uno::UNO_QUERY);
1832 if ( ! xListener.is() )
1833 continue;
1834 xListener->queryTermination( aEvent );
1835 lCalledListener.push_back(xListener);
1837 catch( const css::frame::TerminationVetoException& )
1839 // first veto will stop notification loop.
1840 bVeto = sal_True;
1841 return;
1843 catch( const css::uno::Exception& )
1845 // clean up container.
1846 // E.g. dead remote listener objects can make trouble otherwise.
1847 // Iterator implementation allows removing objects during it's used !
1848 aIterator.remove();
1853 //=============================================================================
1854 void Desktop::impl_sendCancelTerminationEvent(const Desktop::TTerminateListenerList& lCalledListener)
1856 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1858 css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
1859 Desktop::TTerminateListenerList::const_iterator pIt;
1860 for ( pIt = lCalledListener.begin();
1861 pIt != lCalledListener.end ();
1862 ++pIt )
1866 // Note: cancelTermination() is a new and optional interface method !
1867 css::uno::Reference< css::frame::XTerminateListener > xListener = *pIt;
1868 css::uno::Reference< css::frame::XTerminateListener2 > xListenerGeneration2(xListener, css::uno::UNO_QUERY);
1869 if ( ! xListenerGeneration2.is() )
1870 continue;
1871 xListenerGeneration2->cancelTermination( aEvent );
1873 catch( const css::uno::Exception& )
1878 //=============================================================================
1879 void Desktop::impl_sendNotifyTerminationEvent()
1881 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1883 ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ) );
1884 if ( ! pContainer )
1885 return;
1887 css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
1889 ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
1890 while ( aIterator.hasMoreElements() )
1894 css::uno::Reference< css::frame::XTerminateListener > xListener(aIterator.next(), css::uno::UNO_QUERY);
1895 if ( ! xListener.is() )
1896 continue;
1897 xListener->notifyTermination( aEvent );
1899 catch( const css::uno::Exception& )
1901 // clean up container.
1902 // E.g. dead remote listener objects can make trouble otherwise.
1903 // Iterator implementation allows removing objects during it's used !
1904 aIterator.remove();
1909 //=============================================================================
1910 ::sal_Bool Desktop::impl_closeFrames(::sal_Bool bAllowUI)
1912 SYNCHRONIZED_START
1913 ReadGuard aReadLock( m_aLock );
1914 css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > lFrames = m_aChildTaskContainer.getAllElements();
1915 aReadLock.unlock();
1916 SYNCHRONIZED_END
1918 ::sal_Int32 c = lFrames.getLength();
1919 ::sal_Int32 i = 0;
1920 ::sal_Int32 nNonClosedFrames = 0;
1922 for( i=0; i<c; ++i )
1926 css::uno::Reference< css::frame::XFrame > xFrame = lFrames[i];
1928 // XController.suspend() will show an UI ...
1929 // Use it in case it was allowed from outside only.
1930 sal_Bool bSuspended = sal_False;
1931 css::uno::Reference< css::frame::XController > xController( xFrame->getController(), css::uno::UNO_QUERY );
1932 if (
1933 ( bAllowUI ) &&
1934 ( xController.is() )
1937 bSuspended = xController->suspend( sal_True );
1938 if ( ! bSuspended )
1940 ++nNonClosedFrames;
1941 continue;
1945 // Try to close frame (in case no UI was allowed without calling XController->suspend() before!)
1946 // But don't deliver ownership to any other one!
1947 // This method can be called again.
1948 css::uno::Reference< css::util::XCloseable > xClose( xFrame, css::uno::UNO_QUERY );
1949 if ( xClose.is() )
1953 xClose->close(sal_False);
1955 catch(const css::util::CloseVetoException&)
1957 // Any internal process of this frame disagree with our request.
1958 // Safe this state but dont break these loop. Other frames has to be closed!
1959 ++nNonClosedFrames;
1961 // Reactivate controller.
1962 // It can happen that XController.suspend() returned true ... but a registered close listener
1963 // throwed these veto exception. Then the controller has to be reactivated. Otherwise
1964 // these document doesnt work any more.
1965 if (
1966 (bSuspended ) &&
1967 (xController.is())
1969 xController->suspend(sal_False);
1972 // If interface XClosable interface exists and was used ...
1973 // it's not allowed to use XComponent->dispose() also !
1974 continue;
1977 // XClosable not supported ?
1978 // Then we have to dispose these frame hardly.
1979 css::uno::Reference< css::lang::XComponent > xDispose( xFrame, css::uno::UNO_QUERY );
1980 if ( xDispose.is() )
1981 xDispose->dispose();
1983 // Don't remove these frame from our child container!
1984 // A frame do it by itself inside close()/dispose() method.
1986 catch(const css::lang::DisposedException&)
1988 // Dispose frames are closed frames.
1989 // So we can count it here .-)
1993 return (nNonClosedFrames < 1);
1996 //_________________________________________________________________________________________________________________
1997 // debug methods
1998 //_________________________________________________________________________________________________________________
2000 /*-----------------------------------------------------------------------------------------------------------------
2001 The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
2002 we return "sal_True". (otherwise sal_False) This mechanism is used to throw an ASSERT!
2003 -----------------------------------------------------------------------------------------------------------------*/
2005 #ifdef ENABLE_ASSERTIONS
2007 //*****************************************************************************************************************
2008 // We work with valid servicemanager only.
2009 sal_Bool Desktop::implcp_ctor( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
2011 return(
2012 ( &xFactory == NULL ) ||
2013 ( xFactory.is() == sal_False )
2017 //*****************************************************************************************************************
2018 // We work with valid listener only.
2019 sal_Bool Desktop::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
2021 return(
2022 ( &xListener == NULL ) ||
2023 ( xListener.is() == sal_False )
2027 //*****************************************************************************************************************
2028 // We work with valid listener only.
2029 sal_Bool Desktop::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
2031 return(
2032 ( &xListener == NULL ) ||
2033 ( xListener.is() == sal_False )
2037 #endif // #ifdef ENABLE_ASSERTIONS
2039 } // namespace framework