update dev300-m57
[ooovba.git] / framework / source / services / desktop.cxx
blobebb9eb0829a6f9b8212f3e28bad634ea251e90eb
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/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>
101 #ifndef __RSC
102 #include <tools/errinf.hxx>
103 #endif
104 #include <comphelper/extract.hxx>
106 //_________________________________________________________________________________________________________________
107 // namespace
108 //_________________________________________________________________________________________________________________
110 namespace framework{
112 //_________________________________________________________________________________________________________________
113 // non exported const
114 //_________________________________________________________________________________________________________________
116 //_________________________________________________________________________________________________________________
117 // non exported definitions
118 //_________________________________________________________________________________________________________________
120 //_________________________________________________________________________________________________________________
121 // declarations
122 //_________________________________________________________________________________________________________________
124 //*****************************************************************************************************************
125 // XInterface, XTypeProvider, XServiceInfo
126 //*****************************************************************************************************************
127 DEFINE_XINTERFACE_15 ( Desktop ,
128 OWeakObject ,
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 ,
155 css::frame::XFrame ,
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,
172 /*Attention
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!
238 @return -
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 ( )
252 // Init member
253 #ifdef ENABLE_ASSERTIONS
254 , m_bIsTerminated ( sal_False ) // see dispose() for further informations!
255 #endif
256 , m_xFactory ( xFactory )
257 , m_aChildTaskContainer ( )
258 , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
259 , m_xFramesHelper ( )
260 , m_xDispatchHelper ( )
261 , m_eLoadState ( E_NOTSET )
262 , m_xLastFrame ( )
263 , m_aInteractionRequest ( )
264 , m_bSuspendQuickstartVeto( sal_False )
265 , m_aCommandOptions ( )
266 , m_sName ( )
267 , m_sTitle ( )
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()
286 @param -
287 @return -
289 @onerror -
290 *//*-*************************************************************************************************************/
291 Desktop::~Desktop()
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 );
303 SYNCHRONIZED_START
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 ;
314 aReadLock.unlock();
315 SYNCHRONIZED_END
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);
322 if ( bVeto )
324 impl_sendCancelTerminationEvent(lCalledTerminationListener);
325 return sal_False;
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);
336 return sal_False;
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.
346 // Note further:
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.
350 // Attention:
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;
393 if ( ! bTerminate )
394 impl_sendCancelTerminationEvent(lCalledTerminationListener);
395 else
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;
403 aWriteLock.unlock();
404 /* UNSAFE AREA ------------------------------------------------------------------------------------- */
405 #endif
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 );
429 return bTerminate;
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 );
440 if ( xInfo.is() )
442 ::rtl::OUString sImplementationName = xInfo->getImplementationName();
444 // SYCNHRONIZED ->
445 WriteGuard aWriteLock( m_aLock );
447 if( sImplementationName.equals(IMPLEMENTATIONNAME_SFXTERMINATOR) )
449 m_xSfxTerminator = xListener;
450 return;
452 if( sImplementationName.equals(IMPLEMENTATIONNAME_PIPETERMINATOR) )
454 m_xPipeTerminator = xListener;
455 return;
457 if( sImplementationName.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER) )
459 m_xQuickLauncher = xListener;
460 return;
462 if( sImplementationName.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER) )
464 m_xSWThreadManager = xListener;
465 return;
468 aWriteLock.unlock();
469 // <- SYCNHRONIZED
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 );
483 if ( xInfo.is() )
485 ::rtl::OUString sImplementationName = xInfo->getImplementationName();
487 // SYCNHRONIZED ->
488 WriteGuard aWriteLock( m_aLock );
490 if( sImplementationName.equals(IMPLEMENTATIONNAME_SFXTERMINATOR) )
492 m_xSfxTerminator.clear();
493 return;
496 if( sImplementationName.equals(IMPLEMENTATIONNAME_PIPETERMINATOR) )
498 m_xPipeTerminator.clear();
499 return;
502 if( sImplementationName.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER) )
504 m_xQuickLauncher.clear();
505 return;
508 if( sImplementationName.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER) )
510 m_xSWThreadManager.clear();
511 return;
514 aWriteLock.unlock();
515 // <- SYCNHRONIZED
518 // No lock required ... container is threadsafe by itself.
519 m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ), xListener );
522 /*-************************************************************************************************************//**
523 @interface XDesktop
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
530 @param -
531 @return A reference to an XEnumerationAccess-object.
533 @onerror We return a null-reference.
534 @threadsafe yes
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 );
546 return xAccess;
549 /*-************************************************************************************************************//**
550 @interface XDesktop
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()
557 @param -
558 @return A reference to the component.
560 @onerror We return a null-reference.
561 @threadsafe yes
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 );
580 return xComponent;
583 /*-************************************************************************************************************//**
584 @interface XDesktop
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()
593 @param -
594 @return A valid reference, if there is an active frame.
595 A null reference , otherwise.
597 @onerror We return a null reference.
598 @threadsafe yes
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 )
615 xLast = xNext;
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.
629 @seealso -
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.
639 @threadsafe yes
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;
656 aReadLock.unlock();
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
677 @param -
678 @return A reference to an accessobject, which can create enumerations of ouer childtasks.
680 @onerror A null reference is returned.
681 @threadsafe yes
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")
686 return NULL;
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 );
692 return xAccess;
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()
708 @param -
709 @return A reference to ouer current active taskchild.
711 @onerror A null reference is returned.
712 @threadsafe yes
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")
722 return NULL;
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.
742 @threadsafe yes
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 >();
763 else
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.
787 @param xInterceptor
788 the interceptor object, which wish to be (de)registered.
790 @threadsafe yes
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
822 @param -
823 @return A reference to the helper.
825 @onerror A null reference is returned.
826 @threadsafe yes
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
842 to do that.
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.
852 @threadsafe yes
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 /*-************************************************************************************************************//**
887 @interface XFrame
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!
892 @seealso -
894 @param -
895 @return -
897 @onerror -
898 @threadsafe -
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 )
924 /* SAFE { */
925 ReadGuard aReadLock( m_aLock );
926 return m_sName;
927 /* } SAFE */
930 //*****************************************************************************************************************
931 void SAL_CALL Desktop::setName( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException )
933 /* SAFE { */
934 WriteGuard aWriteLock( m_aLock );
935 m_sName = sName;
936 aWriteLock.unlock();
937 /* } SAFE */
940 //*****************************************************************************************************************
941 sal_Bool SAL_CALL Desktop::isTop() throw( css::uno::RuntimeException )
943 return sal_True;
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 )
965 return sal_True;
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 )
972 return sal_False;
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 /*-************************************************************************************************************//**
1005 @interface XFrame
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
1010 this method.
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.
1029 @threadsafe yes
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 //-----------------------------------------------------------------------------------------------------
1043 if (
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
1052 return NULL;
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
1061 /* SAFE { */
1062 ReadGuard aReadLock( m_aLock );
1063 css::uno::Reference< css::lang::XMultiServiceFactory > xFactory = m_xFactory;
1064 aReadLock.unlock();
1065 /* } SAFE */
1067 //-----------------------------------------------------------------------------------------------------
1068 // I.I) "_blank"
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 //-----------------------------------------------------------------------------------------------------
1079 // I.II) "_top"
1080 // We are top by definition
1081 //-----------------------------------------------------------------------------------------------------
1082 else
1083 if ( sTargetFrameName==SPECIALTARGET_TOP )
1085 xTarget = this;
1088 //-----------------------------------------------------------------------------------------------------
1089 // I.III) "_self", ""
1090 // This mean this "frame" in every case.
1091 //-----------------------------------------------------------------------------------------------------
1092 else
1093 if (
1094 ( sTargetFrameName==SPECIALTARGET_SELF ) ||
1095 ( sTargetFrameName.getLength()<1 )
1098 xTarget = this;
1101 else
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
1113 /* SAFE { */
1114 aReadLock.lock();
1115 ::rtl::OUString sOwnName = m_sName;
1116 aReadLock.unlock();
1117 /* } SAFE */
1119 //-------------------------------------------------------------------------------------------------
1120 // II.I) SELF
1121 // Check for right name. If it's the searched one return ourself - otherwhise
1122 // ignore this flag.
1123 //-------------------------------------------------------------------------------------------------
1124 if (
1125 (nSearchFlags & css::frame::FrameSearchFlag::SELF) &&
1126 (sOwnName == sTargetFrameName )
1129 xTarget = this;
1132 //-------------------------------------------------------------------------------------------------
1133 // II.II) TASKS
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 //-------------------------------------------------------------------------------------------------
1141 if (
1142 ( ! xTarget.is() ) &&
1143 (nSearchFlags & css::frame::FrameSearchFlag::TASKS)
1146 xTarget = m_aChildTaskContainer.searchOnDirectChildrens(sTargetFrameName);
1149 //-------------------------------------------------------------------------------------------------
1150 // II.III) CHILDREN
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 //-------------------------------------------------------------------------------------------------
1156 if (
1157 ( ! xTarget.is() ) &&
1158 (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
1161 xTarget = m_aChildTaskContainer.searchOnAllChildrens(sTargetFrameName);
1164 //-------------------------------------------------------------------------------------------------
1165 // II.IV) CREATE
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 //-------------------------------------------------------------------------------------------------
1169 if (
1170 ( ! xTarget.is() ) &&
1171 (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
1174 TaskCreator aCreator(xFactory);
1175 xTarget = aCreator.createTask(sTargetFrameName,sal_False);
1179 return xTarget;
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!" )
1190 SYNCHRONIZED_START
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();
1213 SYNCHRONIZED_END
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();
1240 m_xFactory.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
1256 about our dieing!
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.
1261 @seealso -
1263 @param "xListener", reference to valid listener. We don't accept invalid values!
1264 @return -
1266 @onerror -
1267 @threadsafe yes
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
1305 @return -
1307 @onerror -
1308 @threadsafe yes
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()
1340 @param -
1341 @return -
1343 @onerror -
1344 @threadsafe -
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.
1357 @attention a)
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
1369 @return -
1371 @onerror -
1372 @threadsafe yes
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 )
1400 if( ! xAbort.is() )
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();
1422 else
1423 if( aRequest >>= aErrorCodeRequest )
1425 sal_Bool bWarning = ((aErrorCodeRequest.ErrCode & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
1426 if (xApprove.is() && bWarning)
1427 xApprove->select();
1428 else
1429 if (xAbort.is())
1431 xAbort->select();
1432 bAbort = sal_True;
1435 else
1436 if( xAbort.is() )
1438 xAbort->select();
1439 bAbort = sal_True;
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 ...
1446 if (bAbort)
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
1513 @threadsafe yes
1514 *//*-*************************************************************************************************************/
1515 sal_Bool SAL_CALL Desktop::convertFastPropertyValue( css::uno::Any& aConvertedValue ,
1516 css::uno::Any& aOldValue ,
1517 sal_Int32 nHandle ,
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;
1528 switch( nHandle )
1530 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO:
1531 bReturn = PropHelper::willPropertyBeChanged(
1532 css::uno::makeAny(m_bSuspendQuickstartVeto),
1533 aValue,
1534 aOldValue,
1535 aConvertedValue);
1536 break;
1537 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
1538 bReturn = PropHelper::willPropertyBeChanged(
1539 css::uno::makeAny(m_xDispatchRecorderSupplier),
1540 aValue,
1541 aOldValue,
1542 aConvertedValue);
1543 break;
1544 case DESKTOP_PROPHANDLE_TITLE :
1545 bReturn = PropHelper::willPropertyBeChanged(
1546 css::uno::makeAny(m_sTitle),
1547 aValue,
1548 aOldValue,
1549 aConvertedValue);
1550 break;
1553 // Return state of operation.
1554 return bReturn ;
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
1568 @return -
1570 @onerror An exception is thrown.
1571 @threadsafe yes
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 );
1580 switch( nHandle )
1582 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO: aValue >>= m_bSuspendQuickstartVeto;
1583 break;
1584 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER: aValue >>= m_xDispatchRecorderSupplier;
1585 break;
1586 case DESKTOP_PROPHANDLE_TITLE: aValue >>= m_sTitle;
1587 break;
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
1602 @return -
1604 @onerror -
1605 @threadsafe yes
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 );
1614 switch( nHandle )
1616 case DESKTOP_PROPHANDLE_ACTIVEFRAME : aValue <<= m_aChildTaskContainer.getActive();
1617 break;
1618 case DESKTOP_PROPHANDLE_ISPLUGGED : aValue <<= sal_False;
1619 break;
1620 case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO: aValue <<= m_bSuspendQuickstartVeto;
1621 break;
1622 case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER: aValue <<= m_xDispatchRecorderSupplier;
1623 break;
1624 case DESKTOP_PROPHANDLE_TITLE: aValue <<= m_sTitle;
1625 break;
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
1640 @param -
1641 @return structure with property-informations
1643 @onerror -
1644 @threadsafe yes
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
1678 of this object.
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
1688 @param -
1689 @return reference to object with information [XPropertySetInfo]
1691 @onerror -
1692 @threadsafe yes
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;
1705 if( 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!
1710 if( pInfo == NULL )
1712 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
1713 // (Use method "getInfoHelper()".)
1714 static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
1715 pInfo = &xInfo;
1719 return (*pInfo);
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
1727 of founded frame.
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.
1738 @threadsafe yes
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 );
1755 else
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 );
1764 else
1766 // Model not exist - use the controller as component.
1767 xComponent = css::uno::Reference< css::lang::XComponent >( xController, css::uno::UNO_QUERY );
1771 return xComponent;
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()
1782 @param -
1783 @return Static table with information about properties.
1785 @onerror -
1786 @threadsafe yes
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.
1794 // ATTENTION:
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,
1813 ::sal_Bool& bVeto )
1815 bVeto = sal_False;
1817 TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1819 ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ) );
1820 if ( ! pContainer )
1821 return;
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() )
1832 continue;
1833 xListener->queryTermination( aEvent );
1834 lCalledListener.push_back(xListener);
1836 catch( const css::frame::TerminationVetoException& )
1838 // first veto will stop notification loop.
1839 bVeto = sal_True;
1840 return;
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 !
1847 aIterator.remove();
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 ();
1861 ++pIt )
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() )
1869 continue;
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 ) );
1883 if ( ! pContainer )
1884 return;
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() )
1895 continue;
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 !
1903 aIterator.remove();
1908 //=============================================================================
1909 ::sal_Bool Desktop::impl_closeFrames(::sal_Bool bAllowUI)
1911 SYNCHRONIZED_START
1912 ReadGuard aReadLock( m_aLock );
1913 css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > lFrames = m_aChildTaskContainer.getAllElements();
1914 aReadLock.unlock();
1915 SYNCHRONIZED_END
1917 ::sal_Int32 c = lFrames.getLength();
1918 ::sal_Int32 i = 0;
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 );
1931 if (
1932 ( bAllowUI ) &&
1933 ( xController.is() )
1936 bSuspended = xController->suspend( sal_True );
1937 if ( ! bSuspended )
1939 ++nNonClosedFrames;
1940 continue;
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 );
1948 if ( xClose.is() )
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!
1958 ++nNonClosedFrames;
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.
1964 if (
1965 (bSuspended ) &&
1966 (xController.is())
1968 xController->suspend(sal_False);
1971 // If interface XClosable interface exists and was used ...
1972 // it's not allowed to use XComponent->dispose() also !
1973 continue;
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 //_________________________________________________________________________________________________________________
1996 // debug methods
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 )
2010 return(
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 )
2020 return(
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 )
2030 return(
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 )
2041 return(
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 )
2061 return(
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 )
2071 return(
2072 ( &xListener == NULL ) ||
2073 ( xListener.is() == sal_False )
2077 //*****************************************************************************************************************
2078 sal_Bool Desktop::implcp_statusChanged( const css::frame::FeatureStateEvent& aEvent )
2080 return(
2081 ( &aEvent == NULL ) ||
2082 ( aEvent.FeatureDescriptor.getLength() < 1 )
2086 #endif // #ifdef ENABLE_ASSERTIONS
2088 } // namespace framework