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