Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <loadenv/loadenv.hxx>
21 :
22 : #include <loadenv/targethelper.hxx>
23 :
24 : #include <services/desktop.hxx>
25 : #include <helper/ocomponentaccess.hxx>
26 : #include <dispatch/dispatchprovider.hxx>
27 :
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>
36 :
37 : #include <classes/resource.hrc>
38 : #include <classes/fwkresid.hxx>
39 :
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>
63 :
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 <vcl/svapp.hxx>
70 :
71 : #include <tools/errinf.hxx>
72 : #include <comphelper/extract.hxx>
73 :
74 : #include <fwkdllapi.h>
75 :
76 : namespace framework{
77 :
78 : //*****************************************************************************************************************
79 : // XInterface, XTypeProvider, XServiceInfo
80 : //*****************************************************************************************************************
81 360807 : DEFINE_XINTERFACE_16 ( Desktop ,
82 : OWeakObject ,
83 : DIRECT_INTERFACE( css::lang::XTypeProvider ),
84 : DIRECT_INTERFACE( css::lang::XServiceInfo ),
85 : DIRECT_INTERFACE( css::frame::XDesktop2 ),
86 : DIRECT_INTERFACE( css::frame::XDesktop ),
87 : DIRECT_INTERFACE( css::frame::XComponentLoader ),
88 : DIRECT_INTERFACE( css::frame::XTasksSupplier ),
89 : DIRECT_INTERFACE( css::frame::XDispatchProvider ),
90 : DIRECT_INTERFACE( css::frame::XDispatchProviderInterception),
91 : DIRECT_INTERFACE( css::frame::XFramesSupplier ),
92 : DIRECT_INTERFACE( css::frame::XFrame ),
93 : DIRECT_INTERFACE( css::lang::XComponent ),
94 : DIRECT_INTERFACE( css::frame::XDispatchResultListener ),
95 : DIRECT_INTERFACE( css::lang::XEventListener ),
96 : DIRECT_INTERFACE( css::task::XInteractionHandler ),
97 : DIRECT_INTERFACE( css::beans::XPropertySet ),
98 : DIRECT_INTERFACE( css::frame::XUntitledNumbers )
99 : )
100 :
101 14 : DEFINE_XTYPEPROVIDER_16 ( Desktop ,
102 : css::lang::XTypeProvider ,
103 : css::lang::XServiceInfo ,
104 : css::frame::XDesktop2 ,
105 : css::frame::XDesktop ,
106 : css::frame::XComponentLoader ,
107 : css::frame::XTasksSupplier ,
108 : css::frame::XDispatchProvider ,
109 : css::frame::XDispatchProviderInterception ,
110 : css::frame::XFramesSupplier ,
111 : css::frame::XFrame ,
112 : css::lang::XComponent ,
113 : css::frame::XDispatchResultListener ,
114 : css::lang::XEventListener ,
115 : css::task::XInteractionHandler ,
116 : css::beans::XPropertySet ,
117 : css::frame::XUntitledNumbers
118 : )
119 :
120 2435 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE_2( Desktop ,
121 : ::cppu::OWeakObject ,
122 : DECLARE_ASCII("com.sun.star.frame.Desktop" ),
123 : IMPLEMENTATIONNAME_DESKTOP
124 : )
125 :
126 135 : DEFINE_INIT_SERVICE ( Desktop,
127 : {
128 : /*Attention
129 : I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
130 : to create a new instance of this class by our own supported service factory.
131 : see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further information!
132 : */
133 :
134 : //-------------------------------------------------------------------------------------------------------------
135 : // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
136 : // We hold member as reference ... not as pointer too!
137 : // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
138 : // But look on dispose() for right order of deinitialization.
139 : OFrames* pFramesHelper = new OFrames( this, &m_aChildTaskContainer );
140 : m_xFramesHelper = css::uno::Reference< css::frame::XFrames >( static_cast< ::cppu::OWeakObject* >(pFramesHelper), css::uno::UNO_QUERY );
141 :
142 : //-------------------------------------------------------------------------------------------------------------
143 : // Initialize a new dispatchhelper-object to handle dispatches.
144 : // We use these helper as slave for our interceptor helper ... not directly!
145 : // But he is event listener on THIS instance!
146 : DispatchProvider* pDispatchHelper = new DispatchProvider( m_xContext, this );
147 : css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
148 :
149 : //-------------------------------------------------------------------------------------------------------------
150 : // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
151 : // Set created dispatch provider as slowest slave of it.
152 : // Hold interception helper by reference only - not by pointer!
153 : // So it's easiear to destroy it.
154 : InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
155 : m_xDispatchHelper = css::uno::Reference< css::frame::XDispatchProvider >( static_cast< ::cppu::OWeakObject* >(pInterceptionHelper), css::uno::UNO_QUERY );
156 :
157 : OUStringBuffer sUntitledPrefix (256);
158 : sUntitledPrefix.append (OUString( String( FwkResId( STR_UNTITLED_DOCUMENT ))));
159 : sUntitledPrefix.appendAscii (" ");
160 :
161 : ::comphelper::NumberedCollection* pNumbers = new ::comphelper::NumberedCollection ();
162 : m_xTitleNumberGenerator = css::uno::Reference< css::frame::XUntitledNumbers >(static_cast< ::cppu::OWeakObject* >(pNumbers), css::uno::UNO_QUERY_THROW);
163 : pNumbers->setOwner ( static_cast< ::cppu::OWeakObject* >(this) );
164 : pNumbers->setUntitledPrefix ( sUntitledPrefix.makeStringAndClear () );
165 :
166 : // Safe impossible cases
167 : // We can't work without this helper!
168 : LOG_ASSERT2( m_xFramesHelper.is ()==sal_False, "Desktop::Desktop()", "Frames helper is not valid. XFrames, XIndexAccess and XElementAcces are not supported!\n")
169 : LOG_ASSERT2( m_xDispatchHelper.is()==sal_False, "Desktop::Desktop()", "Dispatch helper is not valid. XDispatch will not work correctly!\n" )
170 :
171 : // Enable object for real working!
172 : // Otherwise all calls will be rejected ...
173 : m_aTransactionManager.setWorkingMode( E_WORK );
174 : }
175 : )
176 :
177 : /*-************************************************************************************************************//**
178 : @short standard constructor to create instance by factory
179 : @descr This constructor initialize a new instance of this class by valid factory,
180 : and will be set valid values on his member and baseclasses.
181 :
182 : @attention a) Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
183 : will get over this. (e.g. using of your reference as parameter to initialize some member)
184 : Do such things in DEFINE_INIT_SERVICE() method, which is called automaticly after your ctor!!!
185 : b) Baseclass OBroadcastHelper is a typedef in namespace cppu!
186 : The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
187 : If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
188 : I don't know why! (other compiler not tested .. but it works!)
189 :
190 : @seealso method DEFINE_INIT_SERVICE()
191 :
192 : @param "xFactory" is the multi service manager, which create this instance.
193 : The value must be different from NULL!
194 : @return -
195 :
196 : @onerror We throw an ASSERT in debug version or do nothing in relaese version.
197 : *//*-*************************************************************************************************************/
198 135 : Desktop::Desktop( const css::uno::Reference< css::uno::XComponentContext >& xContext )
199 : // Init baseclasses first
200 : // Attention: Don't change order of initialization!
201 : // ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
202 : // We must guarantee right initialization and a valid value of this to initialize other baseclasses!
203 135 : : ThreadHelpBase ( &Application::GetSolarMutex() )
204 : , TransactionBase ( )
205 135 : , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType > ( m_aLock.getShareableOslMutex() )
206 : , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
207 : , ::cppu::OWeakObject ( )
208 : // Init member
209 : #ifdef ENABLE_ASSERTIONS
210 : , m_bIsTerminated ( sal_False ) // see dispose() for further information!
211 : #endif
212 : , m_xContext ( xContext )
213 : , m_aChildTaskContainer ( )
214 135 : , m_aListenerContainer ( m_aLock.getShareableOslMutex() )
215 : , m_xFramesHelper ( )
216 : , m_xDispatchHelper ( )
217 : , m_eLoadState ( E_NOTSET )
218 : , m_xLastFrame ( )
219 : , m_aInteractionRequest ( )
220 : , m_bSuspendQuickstartVeto( sal_False )
221 : , m_aCommandOptions ( )
222 : , m_sName ( )
223 : , m_sTitle ( )
224 : , m_xDispatchRecorderSupplier( )
225 : , m_xPipeTerminator ( )
226 : , m_xQuickLauncher ( )
227 : , m_xSWThreadManager ( )
228 : , m_xSfxTerminator ( )
229 540 : , m_xTitleNumberGenerator ( )
230 : {
231 : // Safe impossible cases
232 : // We don't accept all incoming parameter.
233 : LOG_ASSERT2( implcp_ctor( xContext ), "Desktop::Desktop()", "Invalid parameter detected!")
234 135 : }
235 :
236 : /*-************************************************************************************************************//**
237 : @short standard destructor
238 : @descr This one do NOTHING! Use dispose() instaed of this.
239 :
240 : @seealso method dispose()
241 :
242 : @param -
243 : @return -
244 :
245 : @onerror -
246 : *//*-*************************************************************************************************************/
247 204 : Desktop::~Desktop()
248 : {
249 : #ifdef ENABLE_ASSERTIONS
250 : // Perhaps we should here do use a real assertion, but make the
251 : // condition more specific? We don't want it to fire in unit tests
252 : // in sc/qa/unit for instance, that don't even have any GUI.
253 : if( !m_bIsTerminated )
254 : fprintf( stderr, "This used to be an assertion failure: Desktop not terminated before being destructed,\n"
255 : "but it is probably not a real problem.\n" );
256 : #endif
257 : LOG_ASSERT2( m_aTransactionManager.getWorkingMode()!=E_CLOSE , "Desktop::~Desktop()", "Who forgot to dispose this service?" )
258 204 : }
259 :
260 : //=============================================================================
261 83 : sal_Bool SAL_CALL Desktop::terminate()
262 : throw( css::uno::RuntimeException )
263 : {
264 83 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
265 :
266 166 : ReadGuard aReadLock( m_aLock ); // start synchronize
267 :
268 166 : css::uno::Reference< css::frame::XTerminateListener > xPipeTerminator = m_xPipeTerminator;
269 166 : css::uno::Reference< css::frame::XTerminateListener > xQuickLauncher = m_xQuickLauncher;
270 166 : css::uno::Reference< css::frame::XTerminateListener > xSWThreadManager = m_xSWThreadManager;
271 166 : css::uno::Reference< css::frame::XTerminateListener > xSfxTerminator = m_xSfxTerminator;
272 :
273 166 : css::lang::EventObject aEvent ( static_cast< ::cppu::OWeakObject* >(this) );
274 83 : ::sal_Bool bAskQuickStart = !m_bSuspendQuickstartVeto ;
275 :
276 83 : aReadLock.unlock(); // end synchronize
277 :
278 : //-------------------------------------------------------------------------------------------------------------
279 : // Ask normal terminate listener. They could stop terminate without closing any open document.
280 166 : Desktop::TTerminateListenerList lCalledTerminationListener;
281 83 : ::sal_Bool bVeto = sal_False;
282 83 : impl_sendQueryTerminationEvent(lCalledTerminationListener, bVeto);
283 83 : if ( bVeto )
284 : {
285 0 : impl_sendCancelTerminationEvent(lCalledTerminationListener);
286 0 : return sal_False;
287 : }
288 :
289 : //-------------------------------------------------------------------------------------------------------------
290 : // try to close all open frames.
291 : // Allow using of any UI ... because Desktop.terminate() was designed as UI functionality in the past.
292 83 : ::sal_Bool bAllowUI = sal_True;
293 83 : ::sal_Bool bFramesClosed = impl_closeFrames(bAllowUI);
294 83 : if ( ! bFramesClosed )
295 : {
296 0 : impl_sendCancelTerminationEvent(lCalledTerminationListener);
297 0 : return sal_False;
298 : }
299 :
300 : //-------------------------------------------------------------------------------------------------------------
301 : // Normal listener had no problem ...
302 : // all frames was closed ...
303 : // now it's time to ask our specialized listener.
304 : // They are handled these way because they wish to hinder the office on termination
305 : // but they wish also closing of all frames.
306 :
307 : // Note further:
308 : // We shouldn't ask quicklauncher in case it was allowed from outside only.
309 : // This is special trick to "ignore existing quick starter" for debug purposes.
310 :
311 : // Attention:
312 : // Order of alled listener is important !
313 : // some of them are harmless .-)
314 : // But some of them can be dangerous. E.g. it would be dangerous if we close our pipe
315 : // and dont terminate in real because another listener throws a veto exception .-)
316 :
317 83 : ::sal_Bool bTerminate = sal_False;
318 : try
319 : {
320 83 : if(
321 166 : ( bAskQuickStart ) &&
322 83 : ( xQuickLauncher.is() )
323 : )
324 : {
325 0 : xQuickLauncher->queryTermination( aEvent );
326 0 : lCalledTerminationListener.push_back( xQuickLauncher );
327 : }
328 :
329 83 : if ( xSWThreadManager.is() )
330 : {
331 1 : xSWThreadManager->queryTermination( aEvent );
332 1 : lCalledTerminationListener.push_back( xSWThreadManager );
333 : }
334 :
335 83 : if ( xPipeTerminator.is() )
336 : {
337 51 : xPipeTerminator->queryTermination( aEvent );
338 51 : lCalledTerminationListener.push_back( xPipeTerminator );
339 : }
340 :
341 83 : if ( xSfxTerminator.is() )
342 : {
343 83 : xSfxTerminator->queryTermination( aEvent );
344 83 : lCalledTerminationListener.push_back( xSfxTerminator );
345 : }
346 :
347 83 : bTerminate = sal_True;
348 : }
349 0 : catch(const css::frame::TerminationVetoException&)
350 : {
351 0 : bTerminate = sal_False;
352 : }
353 :
354 83 : if ( ! bTerminate )
355 0 : impl_sendCancelTerminationEvent(lCalledTerminationListener);
356 : else
357 : {
358 : #ifdef ENABLE_ASSERTIONS
359 : // "Protect" us against dispose before terminate calls!
360 : // see dispose() for further information.
361 : /* SAFE AREA --------------------------------------------------------------------------------------- */
362 : WriteGuard aWriteLock( m_aLock );
363 : m_bIsTerminated = sal_True;
364 : aWriteLock.unlock();
365 : /* UNSAFE AREA ------------------------------------------------------------------------------------- */
366 : #endif
367 :
368 83 : impl_sendNotifyTerminationEvent();
369 :
370 83 : if(
371 166 : ( bAskQuickStart ) &&
372 83 : ( xQuickLauncher.is() )
373 : )
374 : {
375 0 : xQuickLauncher->notifyTermination( aEvent );
376 : }
377 :
378 83 : if ( xSWThreadManager.is() )
379 1 : xSWThreadManager->notifyTermination( aEvent );
380 :
381 83 : if ( xPipeTerminator.is() )
382 51 : xPipeTerminator->notifyTermination( aEvent );
383 :
384 : // Must be realy the last listener to be called.
385 : // Because it shutdown the whole process asynchronous !
386 83 : if ( xSfxTerminator.is() )
387 83 : xSfxTerminator->notifyTermination( aEvent );
388 : }
389 :
390 166 : return bTerminate;
391 : }
392 :
393 : namespace
394 : {
395 : class QuickstartSuppressor
396 : {
397 : Desktop* const m_pDesktop;
398 : css::uno::Reference< css::frame::XTerminateListener > m_xQuickLauncher;
399 : public:
400 0 : QuickstartSuppressor(Desktop* const pDesktop, css::uno::Reference< css::frame::XTerminateListener > xQuickLauncher)
401 : : m_pDesktop(pDesktop)
402 0 : , m_xQuickLauncher(xQuickLauncher)
403 : {
404 : SAL_INFO("fwk.desktop", "temporary removing Quickstarter");
405 0 : if(m_xQuickLauncher.is())
406 0 : m_pDesktop->removeTerminateListener(m_xQuickLauncher);
407 0 : }
408 0 : ~QuickstartSuppressor()
409 0 : {
410 : SAL_INFO("fwk.desktop", "readding Quickstarter");
411 0 : if(m_xQuickLauncher.is())
412 0 : m_pDesktop->addTerminateListener(m_xQuickLauncher);
413 0 : }
414 : };
415 : }
416 :
417 0 : bool SAL_CALL Desktop::terminateQuickstarterToo()
418 : throw( css::uno::RuntimeException )
419 : {
420 0 : QuickstartSuppressor aQuickstartSuppressor(this, m_xQuickLauncher);
421 0 : return terminate();
422 : }
423 :
424 : //=============================================================================
425 555 : void SAL_CALL Desktop::addTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener )
426 : throw( css::uno::RuntimeException )
427 : {
428 555 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
429 :
430 925 : css::uno::Reference< css::lang::XServiceInfo > xInfo( xListener, css::uno::UNO_QUERY );
431 555 : if ( xInfo.is() )
432 : {
433 190 : OUString sImplementationName = xInfo->getImplementationName();
434 :
435 : // SYCNHRONIZED ->
436 195 : WriteGuard aWriteLock( m_aLock );
437 :
438 190 : if( sImplementationName.equals(IMPLEMENTATIONNAME_SFXTERMINATOR) )
439 : {
440 133 : m_xSfxTerminator = xListener;
441 133 : return;
442 : }
443 57 : if( sImplementationName.equals(IMPLEMENTATIONNAME_PIPETERMINATOR) )
444 : {
445 51 : m_xPipeTerminator = xListener;
446 51 : return;
447 : }
448 6 : if( sImplementationName.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER) )
449 : {
450 0 : m_xQuickLauncher = xListener;
451 0 : return;
452 : }
453 6 : if( sImplementationName.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER) )
454 : {
455 1 : m_xSWThreadManager = xListener;
456 1 : return;
457 : }
458 :
459 10 : aWriteLock.unlock();
460 : // <- SYCNHRONIZED
461 : }
462 :
463 : // No lock required ... container is threadsafe by itself.
464 740 : m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ), xListener );
465 : }
466 :
467 : //=============================================================================
468 644 : void SAL_CALL Desktop::removeTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener )
469 : throw( css::uno::RuntimeException )
470 : {
471 644 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
472 :
473 1205 : css::uno::Reference< css::lang::XServiceInfo > xInfo( xListener, css::uno::UNO_QUERY );
474 644 : if ( xInfo.is() )
475 : {
476 88 : OUString sImplementationName = xInfo->getImplementationName();
477 :
478 : // SYCNHRONIZED ->
479 93 : WriteGuard aWriteLock( m_aLock );
480 :
481 88 : if( sImplementationName.equals(IMPLEMENTATIONNAME_SFXTERMINATOR) )
482 : {
483 83 : m_xSfxTerminator.clear();
484 83 : return;
485 : }
486 :
487 5 : if( sImplementationName.equals(IMPLEMENTATIONNAME_PIPETERMINATOR) )
488 : {
489 0 : m_xPipeTerminator.clear();
490 0 : return;
491 : }
492 :
493 5 : if( sImplementationName.equals(IMPLEMENTATIONNAME_QUICKLAUNCHER) )
494 : {
495 0 : m_xQuickLauncher.clear();
496 0 : return;
497 : }
498 :
499 5 : if( sImplementationName.equals(IMPLEMENTATIONNAME_SWTHREADMANAGER) )
500 : {
501 0 : m_xSWThreadManager.clear();
502 0 : return;
503 : }
504 :
505 10 : aWriteLock.unlock();
506 : // <- SYCNHRONIZED
507 : }
508 :
509 : // No lock required ... container is threadsafe by itself.
510 1122 : m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ), xListener );
511 : }
512 :
513 : /*-************************************************************************************************************//**
514 : @interface XDesktop
515 : @short get access to create enumerations of all current components
516 : @descr You will be the owner of the returned object and must delete it if you don't use it again.
517 :
518 : @seealso class TasksAccess
519 : @seealso class TasksEnumeration
520 :
521 : @param -
522 : @return A reference to an XEnumerationAccess-object.
523 :
524 : @onerror We return a null-reference.
525 : @threadsafe yes
526 : *//*-*************************************************************************************************************/
527 85 : css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL Desktop::getComponents() throw( css::uno::RuntimeException )
528 : {
529 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
530 : // Register transaction and reject wrong calls.
531 85 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
532 :
533 : // We use a helper class OComponentAccess to have access on all child components.
534 : // Create it on demand and return it as a reference.
535 85 : OComponentAccess* pAccess = new OComponentAccess( this );
536 85 : css::uno::Reference< css::container::XEnumerationAccess > xAccess( static_cast< ::cppu::OWeakObject* >(pAccess), css::uno::UNO_QUERY );
537 85 : return xAccess;
538 : }
539 :
540 : /*-************************************************************************************************************//**
541 : @interface XDesktop
542 : @short return the current active component
543 : @descr The most current component is the window, model or the controller of the current active frame.
544 :
545 : @seealso method getCurrentFrame()
546 : @seealso method impl_getFrameComponent()
547 :
548 : @param -
549 : @return A reference to the component.
550 :
551 : @onerror We return a null-reference.
552 : @threadsafe yes
553 : *//*-*************************************************************************************************************/
554 0 : css::uno::Reference< css::lang::XComponent > SAL_CALL Desktop::getCurrentComponent() throw( css::uno::RuntimeException )
555 : {
556 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
557 : // Register transaction and reject wrong calls.
558 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
559 :
560 : // Set return value if method failed.
561 0 : css::uno::Reference< css::lang::XComponent > xComponent;
562 :
563 : // Get reference to current frame ...
564 : // ... get component of this frame ... (It can be the window, the model or the controller.)
565 : // ... and return the result.
566 0 : css::uno::Reference< css::frame::XFrame > xCurrentFrame = getCurrentFrame();
567 0 : if( xCurrentFrame.is() == sal_True )
568 : {
569 0 : xComponent = impl_getFrameComponent( xCurrentFrame );
570 : }
571 0 : return xComponent;
572 : }
573 :
574 : /*-************************************************************************************************************//**
575 : @interface XDesktop
576 : @short return the current active frame in hierarchy
577 : @descr There can be more then one different active paths in our frame hierarchy. But only one of them
578 : could be the most active frame (normal he has the focus).
579 : Don't mix it with getActiveFrame()! That will return our current active frame, which must be
580 : a direct child of us and should be a part(!) of an active path.
581 :
582 : @seealso method getActiveFrame()
583 :
584 : @param -
585 : @return A valid reference, if there is an active frame.
586 : A null reference , otherwise.
587 :
588 : @onerror We return a null reference.
589 : @threadsafe yes
590 : *//*-*************************************************************************************************************/
591 239 : css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::getCurrentFrame() throw( css::uno::RuntimeException )
592 : {
593 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
594 : // Register transaction and reject wrong calls.
595 239 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
596 :
597 : // Start search with ouer direct active frame (if it exist!).
598 : // Search on his children for other active frames too.
599 : // Stop if no one could be found and return last of found ones.
600 478 : css::uno::Reference< css::frame::XFramesSupplier > xLast = css::uno::Reference< css::frame::XFramesSupplier >( getActiveFrame(), css::uno::UNO_QUERY );
601 239 : if( xLast.is() == sal_True )
602 : {
603 239 : css::uno::Reference< css::frame::XFramesSupplier > xNext = css::uno::Reference< css::frame::XFramesSupplier >( xLast->getActiveFrame(), css::uno::UNO_QUERY );
604 478 : while( xNext.is() == sal_True )
605 : {
606 0 : xLast = xNext;
607 0 : xNext = css::uno::Reference< css::frame::XFramesSupplier >( xNext->getActiveFrame(), css::uno::UNO_QUERY );
608 239 : }
609 : }
610 478 : return css::uno::Reference< css::frame::XFrame >( xLast, css::uno::UNO_QUERY );
611 : }
612 :
613 : /*-************************************************************************************************************//**
614 : @interface XComponentLoader
615 : @short try to load given URL into a task
616 : @descr You can give us some information about the content, which you will load into a frame.
617 : We search or create this target for you, make a type detection of given URL and try to load it.
618 : As result of this operation we return the new created component or nothing, if loading failed.
619 :
620 : @seealso -
621 :
622 : @param "sURL" , URL, which represant the content
623 : @param "sTargetFrameName" , name of target frame or special value like "_self", "_blank" ...
624 : @param "nSearchFlags" , optional arguments for frame search, if target isn't a special one
625 : @param "lArguments" , optional arguments for loading
626 : @return A valid component reference, if loading was successfully.
627 : A null reference otherwise.
628 :
629 : @onerror We return a null reference.
630 : @threadsafe yes
631 : *//*-*************************************************************************************************************/
632 1092 : css::uno::Reference< css::lang::XComponent > SAL_CALL Desktop::loadComponentFromURL( const OUString& sURL ,
633 : const OUString& sTargetFrameName,
634 : sal_Int32 nSearchFlags ,
635 : const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::io::IOException ,
636 : css::lang::IllegalArgumentException ,
637 : css::uno::RuntimeException )
638 : {
639 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
640 : // Register transaction and reject wrong calls.
641 1092 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
642 : SAL_INFO( "fwk.desktop", "framework (as96863) ::Desktop::loadComponentFromURL" );
643 :
644 2184 : ReadGuard aReadLock(m_aLock);
645 2184 : css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
646 2184 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
647 1092 : aReadLock.unlock();
648 :
649 : SAL_INFO( "fwk.desktop", "PERFORMANCE - Desktop::loadComponentFromURL()" );
650 2184 : return LoadEnv::loadComponentFromURL(xThis, xContext, sURL, sTargetFrameName, nSearchFlags, lArguments);
651 : }
652 :
653 : /*-************************************************************************************************************//**
654 : @interface XTasksSupplier
655 : @short get access to create enumerations of ouer taskchildren
656 : @descr Direct children of desktop are tasks everytime.
657 : Call these method to could create enumerations of it.
658 :
659 : But; Don't forget - you will be the owner of returned object and must release it!
660 : We use a helper class to implement the access interface. They hold a weakreference to us.
661 : It can be, that the desktop is dead - but not your tasksaccess-object! Then they will do nothing!
662 : You can't create enumerations then.
663 :
664 : @attention Normaly we don't need any lock here. We don't work on internal member!
665 :
666 : @seealso class TasksAccess
667 :
668 : @param -
669 : @return A reference to an accessobject, which can create enumerations of ouer childtasks.
670 :
671 : @onerror A null reference is returned.
672 : @threadsafe yes
673 : *//*-*************************************************************************************************************/
674 0 : css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL Desktop::getTasks() throw( css::uno::RuntimeException )
675 : {
676 : LOG_WARNING("Desktop::getTasks()", "Use of obsolete interface XTaskSupplier")
677 0 : return NULL;
678 : }
679 :
680 : /*-************************************************************************************************************//**
681 : @interface XTasksSupplier
682 : @short return current active task of ouer direct children
683 : @descr Desktop children are tasks only ! If we have an active path from desktop
684 : as top to any frame on bottom, we must have an active direct child. His reference is returned here.
685 :
686 : @attention a) Do not confuse it with getCurrentFrame()! The current frame don't must one of ouer direct children.
687 : It can be every frame in subtree and must have the focus (Is the last one of an active path!).
688 : b) We don't need any lock here. Our container is threadsafe himself and live, if we live!
689 :
690 : @seealso method getCurrentFrame()
691 :
692 : @param -
693 : @return A reference to ouer current active taskchild.
694 :
695 : @onerror A null reference is returned.
696 : @threadsafe yes
697 : *//*-*************************************************************************************************************/
698 0 : css::uno::Reference< css::frame::XTask > SAL_CALL Desktop::getActiveTask() throw( css::uno::RuntimeException )
699 : {
700 : LOG_WARNING("Desktop::getActiveTask()", "Use of obsolete interface XTaskSupplier")
701 0 : return NULL;
702 : }
703 :
704 : /*-************************************************************************************************************//**
705 : @interface XDispatchProvider
706 : @short search a dispatcher for given URL
707 : @descr We use a helper implementation (class DispatchProvider) to do so.
708 : So we don't must implement this algorithm twice!
709 :
710 : @attention We don't need any lock here. Our helper is threadsafe himself and live, if we live!
711 :
712 : @seealso class DispatchProvider
713 :
714 : @param "aURL" , URL to dispatch
715 : @param "sTargetFrameName" , name of target frame, who should dispatch these URL
716 : @param "nSearchFlags" , flags to regulate the search
717 : @param "lQueries" , list of queryDispatch() calls!
718 : @return A reference or list of founded dispatch objects for these URL.
719 :
720 : @onerror A null reference is returned.
721 : @threadsafe yes
722 : *//*-*************************************************************************************************************/
723 129 : css::uno::Reference< css::frame::XDispatch > SAL_CALL Desktop::queryDispatch( const css::util::URL& aURL ,
724 : const OUString& sTargetFrameName ,
725 : sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
726 : {
727 129 : const char UNO_PROTOCOL[] = ".uno:";
728 :
729 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
730 : // Register transaction and reject wrong calls.
731 129 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
732 :
733 : // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
734 : // in our hash map. All other protocols are stored with the protocol part.
735 258 : String aCommand( aURL.Main );
736 129 : if ( aURL.Protocol.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL, sizeof( UNO_PROTOCOL )-1 ))
737 129 : aCommand = aURL.Path;
738 :
739 : // Make boost::unordered_map lookup if the current URL is in the disabled list
740 129 : if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
741 0 : return css::uno::Reference< css::frame::XDispatch >();
742 : else
743 : {
744 : // We use a helper to support these interface and an interceptor mechanism.
745 : // Our helper is threadsafe by himself!
746 129 : return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
747 129 : }
748 : }
749 :
750 : //*****************************************************************************************************************
751 1 : 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 )
752 : {
753 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
754 : // Register transaction and reject wrong calls.
755 1 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
756 :
757 1 : return m_xDispatchHelper->queryDispatches( lQueries );
758 : }
759 :
760 : /*-************************************************************************************************************//**
761 : @interface XDipsatchProviderInterception
762 : @short supports registration/deregistration of interception objects, which
763 : are interested on special dispatches.
764 :
765 : @descr Its realy provided by an internal helper, which is used inside the dispatch api too.
766 : @param xInterceptor
767 : the interceptor object, which wish to be (de)registered.
768 :
769 : @threadsafe yes
770 : *//*-*************************************************************************************************************/
771 1 : void SAL_CALL Desktop::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
772 : throw( css::uno::RuntimeException)
773 : {
774 1 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
775 :
776 2 : css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
777 2 : xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
778 1 : }
779 :
780 : //*****************************************************************************************************************
781 1 : void SAL_CALL Desktop::releaseDispatchProviderInterceptor ( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor)
782 : throw( css::uno::RuntimeException)
783 : {
784 1 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
785 :
786 2 : css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
787 2 : xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
788 1 : }
789 :
790 : /*-************************************************************************************************************//**
791 : @interface XFramesSupplier
792 : @short return access to append or remove children on desktop
793 : @descr We don't implement these interface directly. We use a helper class to do this.
794 : If you wish to add or delete children to/from the container, call these method to get
795 : a reference to the helper.
796 :
797 : @attention Helper is threadsafe himself. So we don't need any lock here.
798 :
799 : @seealso class OFrames
800 :
801 : @param -
802 : @return A reference to the helper.
803 :
804 : @onerror A null reference is returned.
805 : @threadsafe yes
806 : *//*-*************************************************************************************************************/
807 8694 : css::uno::Reference< css::frame::XFrames > SAL_CALL Desktop::getFrames() throw( css::uno::RuntimeException )
808 : {
809 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
810 : // Register transaction and reject wrong calls.
811 8694 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
812 :
813 8694 : return m_xFramesHelper;
814 : }
815 :
816 : /*-************************************************************************************************************//**
817 : @interface XFramesSupplier
818 : @short set/get the current active child frame
819 : @descr It must be a task. Direct children of desktop are tasks only! No frames are accepted.
820 : We don't save this information directly in this class. We use ouer container-helper
821 : to do that.
822 :
823 : @attention Helper is threadsafe himself. So we don't need any lock here.
824 :
825 : @seealso class OFrameContainer
826 :
827 : @param "xFrame", new active frame (must be valid!)
828 : @return A reference to ouer current active childtask, if anyone exist.
829 :
830 : @onerror A null reference is returned.
831 : @threadsafe yes
832 : *//*-*************************************************************************************************************/
833 929 : void SAL_CALL Desktop::setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException )
834 : {
835 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
836 : // Register transaction and reject wrong calls.
837 929 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
838 :
839 : // Get old active frame first.
840 : // If nothing will change - do nothing!
841 : // Otherwise set new active frame ...
842 : // and deactivate last frame.
843 : // It's necessary for our FrameActionEvent listener on a frame!
844 1858 : css::uno::Reference< css::frame::XFrame > xLastActiveChild = m_aChildTaskContainer.getActive();
845 929 : if( xLastActiveChild != xFrame )
846 : {
847 918 : m_aChildTaskContainer.setActive( xFrame );
848 918 : if( xLastActiveChild.is() == sal_True )
849 : {
850 23 : xLastActiveChild->deactivate();
851 : }
852 929 : }
853 929 : }
854 :
855 : //*****************************************************************************************************************
856 1102 : css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::getActiveFrame() throw( css::uno::RuntimeException )
857 : {
858 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
859 : // Register transaction and reject wrong calls.
860 1102 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
861 :
862 1102 : return m_aChildTaskContainer.getActive();
863 : }
864 :
865 : /*-************************************************************************************************************//**
866 : @interface XFrame
867 : @short non implemented methods!
868 : @descr Some method make no sense for our desktop! He has no window or parent or ...
869 : So we should implement it empty and warn programmer, if he use it!
870 :
871 : @seealso -
872 :
873 : @param -
874 : @return -
875 :
876 : @onerror -
877 : @threadsafe -
878 : *//*-*************************************************************************************************************/
879 1 : void SAL_CALL Desktop::initialize( const css::uno::Reference< css::awt::XWindow >& ) throw( css::uno::RuntimeException )
880 : {
881 1 : }
882 :
883 : //*****************************************************************************************************************
884 1103 : css::uno::Reference< css::awt::XWindow > SAL_CALL Desktop::getContainerWindow() throw( css::uno::RuntimeException )
885 : {
886 1103 : return css::uno::Reference< css::awt::XWindow >();
887 : }
888 :
889 : //*****************************************************************************************************************
890 0 : void SAL_CALL Desktop::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& /*xCreator*/ ) throw( css::uno::RuntimeException )
891 : {
892 0 : }
893 :
894 : //*****************************************************************************************************************
895 0 : css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Desktop::getCreator() throw( css::uno::RuntimeException )
896 : {
897 0 : return css::uno::Reference< css::frame::XFramesSupplier >();
898 : }
899 :
900 : //*****************************************************************************************************************
901 2 : OUString SAL_CALL Desktop::getName() throw( css::uno::RuntimeException )
902 : {
903 : /* SAFE { */
904 2 : ReadGuard aReadLock( m_aLock );
905 2 : return m_sName;
906 : /* } SAFE */
907 : }
908 :
909 : //*****************************************************************************************************************
910 1 : void SAL_CALL Desktop::setName( const OUString& sName ) throw( css::uno::RuntimeException )
911 : {
912 : /* SAFE { */
913 1 : WriteGuard aWriteLock( m_aLock );
914 1 : m_sName = sName;
915 1 : aWriteLock.unlock();
916 : /* } SAFE */
917 1 : }
918 :
919 : //*****************************************************************************************************************
920 1 : sal_Bool SAL_CALL Desktop::isTop() throw( css::uno::RuntimeException )
921 : {
922 1 : return sal_True;
923 : }
924 :
925 : //*****************************************************************************************************************
926 924 : void SAL_CALL Desktop::activate() throw( css::uno::RuntimeException )
927 : {
928 : // Desktop is activae always ... but sometimes our frames try to activate
929 : // the complete path from bottom to top ... And our desktop is the topest frame :-(
930 : // So - please don't show any assertions here. Do nothing!
931 924 : }
932 :
933 : //*****************************************************************************************************************
934 3 : void SAL_CALL Desktop::deactivate() throw( css::uno::RuntimeException )
935 : {
936 : // Desktop is activae always ... but sometimes our frames try to deactivate
937 : // the complete path from bottom to top ... And our desktop is the topest frame :-(
938 : // So - please don't show any assertions here. Do nothing!
939 3 : }
940 :
941 : //*****************************************************************************************************************
942 1 : sal_Bool SAL_CALL Desktop::isActive() throw( css::uno::RuntimeException )
943 : {
944 1 : return sal_True;
945 : }
946 :
947 : //*****************************************************************************************************************
948 1 : sal_Bool SAL_CALL Desktop::setComponent( const css::uno::Reference< css::awt::XWindow >& /*xComponentWindow*/ ,
949 : const css::uno::Reference< css::frame::XController >& /*xController*/ ) throw( css::uno::RuntimeException )
950 : {
951 1 : return sal_False;
952 : }
953 :
954 : //*****************************************************************************************************************
955 3 : css::uno::Reference< css::awt::XWindow > SAL_CALL Desktop::getComponentWindow() throw( css::uno::RuntimeException )
956 : {
957 3 : return css::uno::Reference< css::awt::XWindow >();
958 : }
959 :
960 : //*****************************************************************************************************************
961 3 : css::uno::Reference< css::frame::XController > SAL_CALL Desktop::getController() throw( css::uno::RuntimeException )
962 : {
963 3 : return css::uno::Reference< css::frame::XController >();
964 : }
965 :
966 : //*****************************************************************************************************************
967 2 : void SAL_CALL Desktop::contextChanged() throw( css::uno::RuntimeException )
968 : {
969 2 : }
970 :
971 : //*****************************************************************************************************************
972 1 : void SAL_CALL Desktop::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& ) throw( css::uno::RuntimeException )
973 : {
974 1 : }
975 :
976 : //*****************************************************************************************************************
977 : // css::frame::XFrame
978 : //*****************************************************************************************************************
979 1 : void SAL_CALL Desktop::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& ) throw( css::uno::RuntimeException )
980 : {
981 1 : }
982 :
983 : /*-************************************************************************************************************//**
984 : @interface XFrame
985 : @short try to find a frame with special parameters
986 : @descr This method searches for a frame with the specified name.
987 : Frames may contain other frames (e.g. a frameset) and may
988 : be contained in other frames. This hierarchie ist searched by
989 : this method.
990 : First some special names are taken into account, i.e. "",
991 : "_self", "_top", "_parent" etc. The FrameSearchFlags are ignored
992 : when comparing these names with aTargetFrameName, further steps are
993 : controlled by the FrameSearchFlags. If allowed, the name of the frame
994 : itself is compared with the desired one, then ( again if allowed )
995 : the method findFrame is called for all children of the frame.
996 : If no Frame with the given name is found until the top frames container,
997 : a new top Frame is created, if this is allowed by a special
998 : FrameSearchFlag. The new Frame also gets the desired name.
999 : We use a helper to get right search direction and react in a right manner.
1000 :
1001 : @seealso class TargetFinder
1002 :
1003 : @param "sTargetFrameName" , name of searched frame
1004 : @param "nSearchFlags" , flags to regulate search
1005 : @return A reference to an existing frame in hierarchy, if it exist.
1006 :
1007 : @onerror A null reference is returned.
1008 : @threadsafe yes
1009 : *//*-*************************************************************************************************************/
1010 1105 : css::uno::Reference< css::frame::XFrame > SAL_CALL Desktop::findFrame( const OUString& sTargetFrameName ,
1011 : sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException )
1012 : {
1013 1105 : css::uno::Reference< css::frame::XFrame > xTarget;
1014 :
1015 : //-----------------------------------------------------------------------------------------------------
1016 : // 0) Ignore wrong parameter!
1017 : // We doesn't support search for following special targets.
1018 : // If we reject this requests - we mustnt check for such names
1019 : // in following code again and again. If we do not so -wrong
1020 : // search results can occure!
1021 : //-----------------------------------------------------------------------------------------------------
1022 2210 : if (
1023 6630 : (sTargetFrameName==SPECIALTARGET_DEFAULT ) || // valid for dispatches - not for findFrame()!
1024 5525 : (sTargetFrameName==SPECIALTARGET_MENUBAR ) || // valid for dispatches - not for findFrame()!
1025 8840 : (sTargetFrameName==SPECIALTARGET_PARENT ) || // we have no parent by definition
1026 3315 : (sTargetFrameName==SPECIALTARGET_BEAMER ) // beamer frames are allowed as child of tasks only -
1027 : // and they exist more then ones. We have no idea which our sub tasks is the right one
1028 : )
1029 : {
1030 0 : return NULL;
1031 : }
1032 :
1033 : //-----------------------------------------------------------------------------------------------------
1034 : // I) check for special defined targets first which must be handled exclusive.
1035 : // force using of "if() else if() ..."
1036 : //-----------------------------------------------------------------------------------------------------
1037 :
1038 : // get threadsafe some necessary member which are neccessary for following functionality
1039 : /* SAFE { */
1040 2210 : ReadGuard aReadLock( m_aLock );
1041 2210 : css::uno::Reference< css::uno::XComponentContext> xContext = m_xContext;
1042 1105 : aReadLock.unlock();
1043 : /* } SAFE */
1044 :
1045 : //-----------------------------------------------------------------------------------------------------
1046 : // I.I) "_blank"
1047 : // create a new task as child of this desktop instance
1048 : // Note: Used helper TaskCreator use us automaticly ...
1049 : //-----------------------------------------------------------------------------------------------------
1050 1105 : if ( sTargetFrameName==SPECIALTARGET_BLANK )
1051 : {
1052 1098 : TaskCreator aCreator( xContext );
1053 1098 : xTarget = aCreator.createTask(sTargetFrameName,sal_False);
1054 : }
1055 :
1056 : //-----------------------------------------------------------------------------------------------------
1057 : // I.II) "_top"
1058 : // We are top by definition
1059 : //-----------------------------------------------------------------------------------------------------
1060 7 : else if ( sTargetFrameName==SPECIALTARGET_TOP )
1061 : {
1062 0 : xTarget = this;
1063 : }
1064 :
1065 : //-----------------------------------------------------------------------------------------------------
1066 : // I.III) "_self", ""
1067 : // This mean this "frame" in every case.
1068 : //-----------------------------------------------------------------------------------------------------
1069 14 : else if (
1070 27 : ( sTargetFrameName==SPECIALTARGET_SELF ) ||
1071 6 : ( sTargetFrameName.isEmpty() )
1072 : )
1073 : {
1074 1 : xTarget = this;
1075 : }
1076 :
1077 : else
1078 : {
1079 : //-------------------------------------------------------------------------------------------------
1080 : // II) otherwise use optional given search flags
1081 : // force using of combinations of such flags. means no "else" part of use if() statements.
1082 : // But we ust break further searches if target was already found.
1083 : // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
1084 : // TASK and CREATE are handled special.
1085 : // But note: Such flags are not valid for the desktop - especialy SIBLINGS or PARENT.
1086 : //-------------------------------------------------------------------------------------------------
1087 :
1088 : // get threadsafe some necessary member which are neccessary for following functionality
1089 : /* SAFE { */
1090 6 : aReadLock.lock();
1091 6 : OUString sOwnName = m_sName;
1092 6 : aReadLock.unlock();
1093 : /* } SAFE */
1094 :
1095 : //-------------------------------------------------------------------------------------------------
1096 : // II.I) SELF
1097 : // Check for right name. If it's the searched one return ourself - otherwise
1098 : // ignore this flag.
1099 : //-------------------------------------------------------------------------------------------------
1100 6 : if (
1101 12 : (nSearchFlags & css::frame::FrameSearchFlag::SELF) &&
1102 6 : (sOwnName == sTargetFrameName )
1103 : )
1104 : {
1105 0 : xTarget = this;
1106 : }
1107 :
1108 : //-------------------------------------------------------------------------------------------------
1109 : // II.II) TASKS
1110 : // This is a special flag. Normaly it regulate search inside tasks and forbid access to parent trees.
1111 : // But the desktop exists outside such task trees. They are our sub trees. So the desktop implement
1112 : // a special feature: We use it to start search on our direct children only. That means we supress
1113 : // search on ALL child frames. May that can be useful to get access on opened document tasks
1114 : // only without filter out all non realy required sub frames ...
1115 : // Used helper method on our container doesn't create any frame - its a search only.
1116 : //-------------------------------------------------------------------------------------------------
1117 6 : if (
1118 12 : ( ! xTarget.is() ) &&
1119 6 : (nSearchFlags & css::frame::FrameSearchFlag::TASKS)
1120 : )
1121 : {
1122 6 : xTarget = m_aChildTaskContainer.searchOnDirectChildrens(sTargetFrameName);
1123 : }
1124 :
1125 : //-------------------------------------------------------------------------------------------------
1126 : // II.III) CHILDREN
1127 : // Search on all children for the given target name.
1128 : // An empty name value can't occure here - because it must be already handled as "_self"
1129 : // before. Used helper function of container doesn't create any frame.
1130 : // It makes a deep search only.
1131 : //-------------------------------------------------------------------------------------------------
1132 6 : if (
1133 10 : ( ! xTarget.is() ) &&
1134 4 : (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
1135 : )
1136 : {
1137 4 : xTarget = m_aChildTaskContainer.searchOnAllChildrens(sTargetFrameName);
1138 : }
1139 :
1140 : //-------------------------------------------------------------------------------------------------
1141 : // II.IV) CREATE
1142 : // If we haven't found any valid target frame by using normal flags - but user allowed us to create
1143 : // a new one ... we should do that. Used TaskCreator use us automaticly as parent!
1144 : //-------------------------------------------------------------------------------------------------
1145 6 : if (
1146 10 : ( ! xTarget.is() ) &&
1147 4 : (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
1148 : )
1149 : {
1150 4 : TaskCreator aCreator( xContext );
1151 4 : xTarget = aCreator.createTask(sTargetFrameName,sal_False);
1152 6 : }
1153 : }
1154 :
1155 2210 : return xTarget;
1156 : }
1157 :
1158 : //=============================================================================
1159 134 : void SAL_CALL Desktop::dispose()
1160 : throw( css::uno::RuntimeException )
1161 : {
1162 : // Safe impossible cases
1163 : // It's an programming error if dispose is called before terminate!
1164 :
1165 : // But if you just ignore the assertion (which happens in unit
1166 : // tests for instance in sc/qa/unit) nothing bad happens.
1167 : #ifdef ENABLE_ASSERTIONS
1168 : if( !m_bIsTerminated )
1169 : fprintf( stderr, "This used to be an assertion failure: Desktop disposed before terminating it,\n"
1170 : "but nothing bad seems to happen anyway?\n" );
1171 : #endif
1172 :
1173 134 : WriteGuard aWriteLock( m_aLock ); // start synchronize
1174 :
1175 : // Look for multiple calls of this method!
1176 : // If somewhere call dispose() twice - he will be stopped here realy!!!
1177 268 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1178 :
1179 : // Now - we are alone and its the first call of this method ...
1180 : // otherwise call before had thrown a DisposedException / hopefully .-)
1181 : // But we dont use the transaction object created before ... we reset it immediately ...
1182 : // two lines of code ... for what ?
1183 : // The answer: We wished to synchronize concurrent dispose() calls -> OK
1184 : // But next line will wait for all currently running transaction (even if they
1185 : // are running within the same thread!) So we would block ourself there if aTransaction
1186 : // will stay registered .-)
1187 134 : aTransaction.stop();
1188 :
1189 : // Disable this instance for further work.
1190 : // This will wait for all current running transactions ...
1191 : // and reject all new incoming requests!
1192 134 : m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
1193 :
1194 134 : aWriteLock.unlock(); // end synchronize
1195 :
1196 : // Following lines of code can be called outside a synchronized block ...
1197 : // Because our transaction manager will block all new requests to this object.
1198 : // So nobody can use us any longer.
1199 : // Exception: Only removing of listener will work ... and this code cant be dangerous.
1200 :
1201 : // First we has to kill all listener connections.
1202 : // They might rely on our member and can hinder us on releasing them.
1203 268 : css::uno::Reference< css::uno::XInterface > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1204 268 : css::lang::EventObject aEvent( xThis );
1205 134 : m_aListenerContainer.disposeAndClear( aEvent );
1206 :
1207 : // Clear our child task container and forget all task references hardly.
1208 : // Normaly all open document was already closed by our terminate() function before ...
1209 : // New opened frames will have a problem now .-)
1210 134 : m_aChildTaskContainer.clear();
1211 :
1212 : // Dispose our helper too.
1213 268 : css::uno::Reference< css::lang::XEventListener > xFramesHelper( m_xFramesHelper, css::uno::UNO_QUERY );
1214 134 : if( xFramesHelper.is() )
1215 0 : xFramesHelper->disposing( aEvent );
1216 :
1217 : // At least clean up other member references.
1218 134 : m_xDispatchHelper.clear();
1219 134 : m_xFramesHelper.clear();
1220 134 : m_xLastFrame.clear();
1221 134 : m_xContext.clear();
1222 :
1223 134 : m_xPipeTerminator.clear();
1224 134 : m_xQuickLauncher.clear();
1225 134 : m_xSWThreadManager.clear();
1226 134 : m_xSfxTerminator.clear();
1227 :
1228 : // From this point nothing will work further on this object ...
1229 : // excepting our dtor() .-)
1230 268 : m_aTransactionManager.setWorkingMode( E_CLOSE );
1231 134 : }
1232 :
1233 : /*-************************************************************************************************************//**
1234 : @interface XComponent
1235 : @short add/remove listener for dispose events
1236 : @descr Add an event listener to this object, if you whish to get information
1237 : about our dieing!
1238 : You must releas ethis listener reference during your own disposing() method.
1239 :
1240 : @attention Our container is threadsafe himeslf. So we doesn't need any lock here.
1241 :
1242 : @seealso -
1243 :
1244 : @param "xListener", reference to valid listener. We don't accept invalid values!
1245 : @return -
1246 :
1247 : @onerror -
1248 : @threadsafe yes
1249 : *//*-*************************************************************************************************************/
1250 88 : void SAL_CALL Desktop::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
1251 : {
1252 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1253 : // Safe impossible cases
1254 : // Method not defined for all incoming parameter.
1255 : LOG_ASSERT2( implcp_addEventListener( xListener ), "Desktop::addEventListener()", "Invalid parameter detected!" )
1256 : // Register transaction and reject wrong calls.
1257 88 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1258 :
1259 88 : m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >*) NULL ), xListener );
1260 88 : }
1261 :
1262 : //*****************************************************************************************************************
1263 52 : void SAL_CALL Desktop::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException )
1264 : {
1265 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1266 : // Safe impossible cases
1267 : // Method not defined for all incoming parameter.
1268 : LOG_ASSERT2( implcp_removeEventListener( xListener ), "Desktop::removeEventListener()", "Invalid parameter detected!" )
1269 : // Register transaction and reject wrong calls.
1270 52 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1271 :
1272 52 : m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >*) NULL ), xListener );
1273 52 : }
1274 :
1275 : /*-************************************************************************************************************//**
1276 : @interface XDispatchResultListener
1277 : @short callback for dispatches
1278 : @descr To support our method "loadComponentFromURL()" we are listener on temp. created dispatcher.
1279 : They call us back in this method "statusChanged()". As source of given state event, they give us a
1280 : reference to the target frame, in which dispatch was loaded! So we can use it to return his component
1281 : to caller! If no target exist ... ??!!
1282 :
1283 : @seealso method loadComponentFromURL()
1284 :
1285 : @param "aEvent", state event which (hopefully) valid information
1286 : @return -
1287 :
1288 : @onerror -
1289 : @threadsafe yes
1290 : *//*-*************************************************************************************************************/
1291 0 : void SAL_CALL Desktop::dispatchFinished( const css::frame::DispatchResultEvent& aEvent ) throw( css::uno::RuntimeException )
1292 : {
1293 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1294 : // Register transaction and reject wrong calls.
1295 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1296 :
1297 : /* SAFE AREA ------------------------------------------------------------------------------------------- */
1298 0 : WriteGuard aWriteLock( m_aLock );
1299 0 : if( m_eLoadState != E_INTERACTION )
1300 : {
1301 0 : m_xLastFrame = css::uno::Reference< css::frame::XFrame >();
1302 0 : m_eLoadState = E_FAILED ;
1303 0 : if( aEvent.State == css::frame::DispatchResultState::SUCCESS )
1304 : {
1305 0 : css::uno::Reference < css::frame::XFrame > xFrame;
1306 0 : if ( aEvent.Result >>= m_xLastFrame )
1307 0 : m_eLoadState = E_SUCCESSFUL;
1308 : }
1309 0 : }
1310 : /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
1311 0 : }
1312 :
1313 : /*-************************************************************************************************************//**
1314 : @interface XEventListener
1315 : @short not implemented!
1316 : @descr We are a status listener ... and so we must be an event listener too ... But we doesn't need it realy!
1317 : We are a temp. listener only and our lifetime isn't smaller then of our temp. used dispatcher.
1318 :
1319 : @seealso method loadComponentFromURL()
1320 :
1321 : @param -
1322 : @return -
1323 :
1324 : @onerror -
1325 : @threadsafe -
1326 : *//*-*************************************************************************************************************/
1327 0 : void SAL_CALL Desktop::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
1328 : {
1329 : LOG_ERROR( "Desktop::disposing()", "Algorithm error! Normaly desktop is temp. listener ... not all the time. So this method shouldn't be called." )
1330 0 : }
1331 :
1332 : /*-************************************************************************************************************//**
1333 : @interface XInteractionHandler
1334 : @short callback for loadComponentFromURL for detected exceptions during load proccess
1335 : @descr In this case we must cancel loading and throw these detected exception again as result
1336 : of our own called method.
1337 :
1338 : @attention a)
1339 : Normal loop in loadComponentFromURL() breaks on setted member m_eLoadState during callback statusChanged().
1340 : But these interaction feature implements second way to do so! So we must look on different callbacks
1341 : for same operation ... and live with it.
1342 : b)
1343 : Search for given continuations too. If any XInteractionAbort exist ... use it to abort further operations
1344 : for currently running operation!
1345 :
1346 : @seealso method loadComponentFromURL()
1347 : @seealso member m_eLoadState
1348 :
1349 : @param "xRequest", request for interaction - normal a wrapped target exception from bottom services
1350 : @return -
1351 :
1352 : @onerror -
1353 : @threadsafe yes
1354 : *//*-*************************************************************************************************************/
1355 0 : void SAL_CALL Desktop::handle( const css::uno::Reference< css::task::XInteractionRequest >& xRequest ) throw( css::uno::RuntimeException )
1356 : {
1357 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1358 : // Register transaction and reject wrong calls.
1359 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1360 :
1361 : // Don't check incoming request!
1362 : // If somewhere starts interaction without right parameter - he maked something wrong.
1363 : // loadComponentFromURL() waits for thjese event - otherwise it yield for ever!
1364 :
1365 : // get packed request and work on it first
1366 : // Attention: Don't set it on internal member BEFORE interaction is finished - because
1367 : // "loadComponentFromURL()" yield tills this member is changed. If we do it before
1368 : // interaction finish we can't guarantee right functionality. May be we cancel load process to erliear ...
1369 0 : css::uno::Any aRequest = xRequest->getRequest();
1370 :
1371 : // extract continuations from request
1372 0 : css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations = xRequest->getContinuations();
1373 0 : css::uno::Reference< css::task::XInteractionAbort > xAbort ;
1374 0 : css::uno::Reference< css::task::XInteractionApprove > xApprove ;
1375 0 : css::uno::Reference< css::document::XInteractionFilterSelect > xFilterSelect ;
1376 0 : sal_Bool bAbort = sal_False;
1377 :
1378 0 : sal_Int32 nCount=lContinuations.getLength();
1379 0 : for( sal_Int32 nStep=0; nStep<nCount; ++nStep )
1380 : {
1381 0 : if( ! xAbort.is() )
1382 0 : xAbort = css::uno::Reference< css::task::XInteractionAbort >( lContinuations[nStep], css::uno::UNO_QUERY );
1383 :
1384 0 : if( ! xApprove.is() )
1385 0 : xApprove = css::uno::Reference< css::task::XInteractionApprove >( lContinuations[nStep], css::uno::UNO_QUERY );
1386 :
1387 0 : if( ! xFilterSelect.is() )
1388 0 : xFilterSelect = css::uno::Reference< css::document::XInteractionFilterSelect >( lContinuations[nStep], css::uno::UNO_QUERY );
1389 : }
1390 :
1391 : // differ between abortable interactions (error, unknown filter ...)
1392 : // and other ones (ambigous but not unknown filter ...)
1393 0 : css::task::ErrorCodeRequest aErrorCodeRequest ;
1394 0 : css::document::AmbigousFilterRequest aAmbigousFilterRequest;
1395 0 : if( aRequest >>= aAmbigousFilterRequest )
1396 : {
1397 0 : if( xFilterSelect.is() )
1398 : {
1399 0 : xFilterSelect->setFilter( aAmbigousFilterRequest.SelectedFilter ); // user selected filter wins!
1400 0 : xFilterSelect->select();
1401 : }
1402 : }
1403 0 : else if( aRequest >>= aErrorCodeRequest )
1404 : {
1405 0 : sal_Bool bWarning = ((aErrorCodeRequest.ErrCode & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK);
1406 0 : if (xApprove.is() && bWarning)
1407 0 : xApprove->select();
1408 : else
1409 0 : if (xAbort.is())
1410 : {
1411 0 : xAbort->select();
1412 0 : bAbort = sal_True;
1413 : }
1414 : }
1415 0 : else if( xAbort.is() )
1416 : {
1417 0 : xAbort->select();
1418 0 : bAbort = sal_True;
1419 : }
1420 :
1421 : /* SAFE AREA ------------------------------------------------------------------------------------------- */
1422 : // Ok now it's time to break yield loop of loadComponentFromURL().
1423 : // But only for realy aborted requests!
1424 : // For example warnings will be approved and we wait for any success story ...
1425 0 : if (bAbort)
1426 : {
1427 0 : WriteGuard aWriteLock( m_aLock );
1428 0 : m_eLoadState = E_INTERACTION;
1429 0 : m_aInteractionRequest = aRequest ;
1430 0 : aWriteLock.unlock();
1431 0 : }
1432 : /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
1433 0 : }
1434 :
1435 : //-----------------------------------------------------------------------------
1436 778 : ::sal_Int32 SAL_CALL Desktop::leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent )
1437 : throw (css::lang::IllegalArgumentException,
1438 : css::uno::RuntimeException )
1439 : {
1440 778 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1441 778 : return m_xTitleNumberGenerator->leaseNumber (xComponent);
1442 : }
1443 :
1444 : //-----------------------------------------------------------------------------
1445 772 : void SAL_CALL Desktop::releaseNumber( ::sal_Int32 nNumber )
1446 : throw (css::lang::IllegalArgumentException,
1447 : css::uno::RuntimeException )
1448 : {
1449 772 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1450 772 : m_xTitleNumberGenerator->releaseNumber (nNumber);
1451 772 : }
1452 :
1453 : //-----------------------------------------------------------------------------
1454 0 : void SAL_CALL Desktop::releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent )
1455 : throw (css::lang::IllegalArgumentException,
1456 : css::uno::RuntimeException )
1457 : {
1458 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1459 0 : m_xTitleNumberGenerator->releaseNumberForComponent (xComponent);
1460 0 : }
1461 :
1462 : //-----------------------------------------------------------------------------
1463 3893 : OUString SAL_CALL Desktop::getUntitledPrefix()
1464 : throw (css::uno::RuntimeException)
1465 : {
1466 3893 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1467 3893 : return m_xTitleNumberGenerator->getUntitledPrefix ();
1468 : }
1469 :
1470 : /*-************************************************************************************************************//**
1471 : @short try to convert a property value
1472 : @descr This method is called from helperclass "OPropertySetHelper".
1473 : Don't use this directly!
1474 : You must try to convert the value of given DESKTOP_PROPHANDLE and
1475 : return results of this operation. This will be used to ask vetoable
1476 : listener. If no listener has a veto, we will change value realy!
1477 : ( in method setFastPropertyValue_NoBroadcast(...) )
1478 :
1479 : @attention Methods of OPropertySethelper are safed by using our shared osl mutex! (see ctor!)
1480 : So we must use different locks to make our implementation threadsafe.
1481 :
1482 : @seealso class OPropertySetHelper
1483 : @seealso method setFastPropertyValue_NoBroadcast()
1484 :
1485 : @param "aConvertedValue" new converted value of property
1486 : @param "aOldValue" old value of property
1487 : @param "nHandle" handle of property
1488 : @param "aValue" new value of property
1489 : @return sal_True if value will be changed, sal_FALSE otherway
1490 :
1491 : @onerror IllegalArgumentException, if you call this with an invalid argument
1492 : @threadsafe yes
1493 : *//*-*************************************************************************************************************/
1494 1 : sal_Bool SAL_CALL Desktop::convertFastPropertyValue( css::uno::Any& aConvertedValue ,
1495 : css::uno::Any& aOldValue ,
1496 : sal_Int32 nHandle ,
1497 : const css::uno::Any& aValue ) throw( css::lang::IllegalArgumentException )
1498 : {
1499 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1500 : // Register transaction and reject wrong calls.
1501 1 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1502 :
1503 : // Initialize state with sal_False !!!
1504 : // (Handle can be invalid)
1505 1 : sal_Bool bReturn = sal_False;
1506 :
1507 1 : switch( nHandle )
1508 : {
1509 : case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO:
1510 : bReturn = PropHelper::willPropertyBeChanged(
1511 : css::uno::makeAny(m_bSuspendQuickstartVeto),
1512 : aValue,
1513 : aOldValue,
1514 0 : aConvertedValue);
1515 0 : break;
1516 : case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
1517 : bReturn = PropHelper::willPropertyBeChanged(
1518 : css::uno::makeAny(m_xDispatchRecorderSupplier),
1519 : aValue,
1520 : aOldValue,
1521 0 : aConvertedValue);
1522 0 : break;
1523 : case DESKTOP_PROPHANDLE_TITLE :
1524 : bReturn = PropHelper::willPropertyBeChanged(
1525 : css::uno::makeAny(m_sTitle),
1526 : aValue,
1527 : aOldValue,
1528 1 : aConvertedValue);
1529 1 : break;
1530 : }
1531 :
1532 : // Return state of operation.
1533 1 : return bReturn ;
1534 : }
1535 :
1536 : /*-************************************************************************************************************//**
1537 : @short set value of a transient property
1538 : @descr This method is calling from helperclass "OPropertySetHelper".
1539 : Don't use this directly!
1540 : Handle and value are valid everyway! You must set the new value only.
1541 : After this, baseclass send messages to all listener automaticly.
1542 :
1543 : @seealso class OPropertySetHelper
1544 :
1545 : @param "nHandle" handle of property to change
1546 : @param "aValue" new value of property
1547 : @return -
1548 :
1549 : @onerror An exception is thrown.
1550 : @threadsafe yes
1551 : *//*-*************************************************************************************************************/
1552 1 : void SAL_CALL Desktop::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle ,
1553 : const css::uno::Any& aValue ) throw( css::uno::Exception )
1554 : {
1555 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1556 : // Register transaction and reject wrong calls.
1557 1 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1558 :
1559 1 : switch( nHandle )
1560 : {
1561 0 : case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO: aValue >>= m_bSuspendQuickstartVeto;
1562 0 : break;
1563 0 : case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER: aValue >>= m_xDispatchRecorderSupplier;
1564 0 : break;
1565 1 : case DESKTOP_PROPHANDLE_TITLE: aValue >>= m_sTitle;
1566 1 : break;
1567 1 : }
1568 1 : }
1569 :
1570 : /*-************************************************************************************************************//**
1571 : @short get value of a transient property
1572 : @descr This method is calling from helperclass "OPropertySetHelper".
1573 : Don't use this directly!
1574 :
1575 : @attention We don't need any mutex or lock here ... We use threadsafe container or methods here only!
1576 :
1577 : @seealso class OPropertySetHelper
1578 :
1579 : @param "nHandle" handle of property to change
1580 : @param "aValue" current value of property
1581 : @return -
1582 :
1583 : @onerror -
1584 : @threadsafe yes
1585 : *//*-*************************************************************************************************************/
1586 2 : void SAL_CALL Desktop::getFastPropertyValue( css::uno::Any& aValue ,
1587 : sal_Int32 nHandle ) const
1588 : {
1589 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1590 : // Register transaction and reject wrong calls.
1591 2 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1592 :
1593 2 : switch( nHandle )
1594 : {
1595 0 : case DESKTOP_PROPHANDLE_ACTIVEFRAME : aValue <<= m_aChildTaskContainer.getActive();
1596 0 : break;
1597 0 : case DESKTOP_PROPHANDLE_ISPLUGGED : aValue <<= sal_False;
1598 0 : break;
1599 0 : case DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO: aValue <<= m_bSuspendQuickstartVeto;
1600 0 : break;
1601 0 : case DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER: aValue <<= m_xDispatchRecorderSupplier;
1602 0 : break;
1603 2 : case DESKTOP_PROPHANDLE_TITLE: aValue <<= m_sTitle;
1604 2 : break;
1605 2 : }
1606 2 : }
1607 :
1608 : /*-************************************************************************************************************//**
1609 : @short return structure and information about transient properties
1610 : @descr This method is calling from helperclass "OPropertySetHelper".
1611 : Don't use this directly!
1612 :
1613 : @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
1614 : Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
1615 : So we could have two different mutex/lock mechanism at the same object.
1616 :
1617 : @seealso class OPropertySetHelper
1618 :
1619 : @param -
1620 : @return structure with property-information
1621 :
1622 : @onerror -
1623 : @threadsafe yes
1624 : *//*-*************************************************************************************************************/
1625 10 : ::cppu::IPropertyArrayHelper& SAL_CALL Desktop::getInfoHelper()
1626 : {
1627 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1628 : // Register transaction and reject wrong calls.
1629 10 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1630 :
1631 : // Optimize this method !
1632 : // We initialize a static variable only one time. And we don't must use a mutex at every call!
1633 : // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
1634 : static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
1635 :
1636 10 : if( pInfoHelper == NULL )
1637 : {
1638 : // Ready for multithreading
1639 3 : ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
1640 : // Control this pointer again, another instance can be faster then these!
1641 3 : if( pInfoHelper == NULL )
1642 : {
1643 : // Define static member to give structure of properties to baseclass "OPropertySetHelper".
1644 : // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
1645 : // "sal_True" say: Table is sorted by name.
1646 3 : static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
1647 3 : pInfoHelper = &aInfoHelper;
1648 3 : }
1649 : }
1650 :
1651 10 : return(*pInfoHelper);
1652 : }
1653 :
1654 : /*-************************************************************************************************************//**
1655 : @short return propertysetinfo
1656 : @descr You can call this method to get information about transient properties
1657 : of this object.
1658 :
1659 : @attention You must use global lock (method use static variable) ... and it must be the shareable osl mutex of it.
1660 : Because; our baseclass use this mutex to make his code threadsafe. We use our lock!
1661 : So we could have two different mutex/lock mechanism at the same object.
1662 :
1663 : @seealso class OPropertySetHelper
1664 : @seealso interface XPropertySet
1665 : @seealso interface XMultiPropertySet
1666 :
1667 : @param -
1668 : @return reference to object with information [XPropertySetInfo]
1669 :
1670 : @onerror -
1671 : @threadsafe yes
1672 : *//*-*************************************************************************************************************/
1673 10 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL Desktop::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException)
1674 : {
1675 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1676 : // Register transaction and reject wrong calls.
1677 10 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1678 :
1679 : // Optimize this method !
1680 : // We initialize a static variable only one time. And we don't must use a mutex at every call!
1681 : // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
1682 : static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL;
1683 :
1684 10 : if( pInfo == NULL )
1685 : {
1686 : // Ready for multithreading
1687 3 : ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
1688 : // Control this pointer again, another instance can be faster then these!
1689 3 : if( pInfo == NULL )
1690 : {
1691 : // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
1692 : // (Use method "getInfoHelper()".)
1693 3 : static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
1694 3 : pInfo = &xInfo;
1695 3 : }
1696 : }
1697 :
1698 10 : return (*pInfo);
1699 : }
1700 :
1701 : /*-************************************************************************************************************//**
1702 : @short return current component of current frame
1703 : @descr The desktop himself has no component. But every frame in subtree.
1704 : If somewhere call getCurrentComponent() at this class, we try to find the right frame and
1705 : then we try to become his component. It can be a VCL-component, the model or the controller
1706 : of founded frame.
1707 :
1708 : @attention We don't work on internal member ... so we doesn't need any lock here.
1709 :
1710 : @seealso method getCurrentComponent();
1711 :
1712 : @param "xFrame", reference to valid frame in hierarchy. Method is not defined for invalid values.
1713 : But we don't check these. Its an IMPL-method and caller must use it right!
1714 : @return A reference to found component.
1715 :
1716 : @onerror A null reference is returned.
1717 : @threadsafe yes
1718 : *//*-*************************************************************************************************************/
1719 0 : css::uno::Reference< css::lang::XComponent > Desktop::impl_getFrameComponent( const css::uno::Reference< css::frame::XFrame >& xFrame ) const
1720 : {
1721 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1722 : // Register transaction and reject wrong calls.
1723 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1724 :
1725 : // Set default return value, if method failed.
1726 0 : css::uno::Reference< css::lang::XComponent > xComponent;
1727 : // Does no controller exists?
1728 0 : css::uno::Reference< css::frame::XController > xController = xFrame->getController();
1729 0 : if( xController.is() == sal_False )
1730 : {
1731 : // Controller not exist - use the VCL-component.
1732 0 : xComponent = css::uno::Reference< css::lang::XComponent >( xFrame->getComponentWindow(), css::uno::UNO_QUERY );
1733 : }
1734 : else
1735 : {
1736 : // Does no model exists?
1737 0 : css::uno::Reference< css::frame::XModel > xModel( xController->getModel(), css::uno::UNO_QUERY );
1738 0 : if( xModel.is() == sal_True )
1739 : {
1740 : // Model exist - use the model as component.
1741 0 : xComponent = css::uno::Reference< css::lang::XComponent >( xModel, css::uno::UNO_QUERY );
1742 : }
1743 : else
1744 : {
1745 : // Model not exist - use the controller as component.
1746 0 : xComponent = css::uno::Reference< css::lang::XComponent >( xController, css::uno::UNO_QUERY );
1747 0 : }
1748 : }
1749 :
1750 0 : return xComponent;
1751 : }
1752 :
1753 : /*-************************************************************************************************************//**
1754 : @short create table with information about properties
1755 : @descr We use a helper class to support properties. These class need some information about this.
1756 : These method create a new static description table with name, type, r/w-flags and so on ...
1757 :
1758 : @seealso class OPropertySetHelper
1759 : @seealso method getInfoHelper()
1760 :
1761 : @param -
1762 : @return Static table with information about properties.
1763 :
1764 : @onerror -
1765 : @threadsafe yes
1766 : *//*-*************************************************************************************************************/
1767 3 : const css::uno::Sequence< css::beans::Property > Desktop::impl_getStaticPropertyDescriptor()
1768 : {
1769 : // Create a property array to initialize sequence!
1770 : // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
1771 : // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
1772 : // It's necessary for methods of OPropertySetHelper.
1773 : // ATTENTION:
1774 : // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
1775 :
1776 : const css::beans::Property pProperties[] =
1777 : {
1778 3 : 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 ),
1779 3 : css::beans::Property( DESKTOP_PROPNAME_DISPATCHRECORDERSUPPLIER , DESKTOP_PROPHANDLE_DISPATCHRECORDERSUPPLIER, ::getCppuType((const css::uno::Reference< css::frame::XDispatchRecorderSupplier >*)NULL), css::beans::PropertyAttribute::TRANSIENT ),
1780 3 : css::beans::Property( DESKTOP_PROPNAME_ISPLUGGED , DESKTOP_PROPHANDLE_ISPLUGGED , ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY ),
1781 3 : css::beans::Property( DESKTOP_PROPNAME_SUSPENDQUICKSTARTVETO , DESKTOP_PROPHANDLE_SUSPENDQUICKSTARTVETO , ::getBooleanCppuType() , css::beans::PropertyAttribute::TRANSIENT ),
1782 3 : css::beans::Property( DESKTOP_PROPNAME_TITLE , DESKTOP_PROPHANDLE_TITLE , ::getCppuType((const OUString*)NULL) , css::beans::PropertyAttribute::TRANSIENT ),
1783 33 : };
1784 : // Use it to initialize sequence!
1785 3 : const css::uno::Sequence< css::beans::Property > lPropertyDescriptor( pProperties, DESKTOP_PROPCOUNT );
1786 : // Return "PropertyDescriptor"
1787 18 : return lPropertyDescriptor;
1788 : }
1789 :
1790 : //=============================================================================
1791 83 : void Desktop::impl_sendQueryTerminationEvent(Desktop::TTerminateListenerList& lCalledListener,
1792 : ::sal_Bool& bVeto )
1793 : {
1794 83 : bVeto = sal_False;
1795 :
1796 83 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1797 :
1798 83 : ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ) );
1799 83 : if ( ! pContainer )
1800 54 : return;
1801 :
1802 58 : css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
1803 :
1804 58 : ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
1805 123 : while ( aIterator.hasMoreElements() )
1806 : {
1807 : try
1808 : {
1809 65 : css::uno::Reference< css::frame::XTerminateListener > xListener(aIterator.next(), css::uno::UNO_QUERY);
1810 65 : if ( ! xListener.is() )
1811 0 : continue;
1812 65 : xListener->queryTermination( aEvent );
1813 65 : lCalledListener.push_back(xListener);
1814 : }
1815 0 : catch( const css::frame::TerminationVetoException& )
1816 : {
1817 : // first veto will stop notification loop.
1818 0 : bVeto = sal_True;
1819 0 : return;
1820 : }
1821 2 : catch( const css::uno::Exception& )
1822 : {
1823 : // clean up container.
1824 : // E.g. dead remote listener objects can make trouble otherwise.
1825 : // Iterator implementation allows removing objects during it's used !
1826 1 : aIterator.remove();
1827 : }
1828 29 : }
1829 : }
1830 :
1831 : //=============================================================================
1832 0 : void Desktop::impl_sendCancelTerminationEvent(const Desktop::TTerminateListenerList& lCalledListener)
1833 : {
1834 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1835 :
1836 0 : css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
1837 0 : Desktop::TTerminateListenerList::const_iterator pIt;
1838 0 : for ( pIt = lCalledListener.begin();
1839 0 : pIt != lCalledListener.end ();
1840 : ++pIt )
1841 : {
1842 : try
1843 : {
1844 : // Note: cancelTermination() is a new and optional interface method !
1845 0 : css::uno::Reference< css::frame::XTerminateListener > xListener = *pIt;
1846 0 : css::uno::Reference< css::frame::XTerminateListener2 > xListenerGeneration2(xListener, css::uno::UNO_QUERY);
1847 0 : if ( ! xListenerGeneration2.is() )
1848 0 : continue;
1849 0 : xListenerGeneration2->cancelTermination( aEvent );
1850 : }
1851 0 : catch( const css::uno::Exception& )
1852 : {}
1853 0 : }
1854 0 : }
1855 :
1856 : //=============================================================================
1857 83 : void Desktop::impl_sendNotifyTerminationEvent()
1858 : {
1859 83 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1860 :
1861 83 : ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTerminateListener >*) NULL ) );
1862 83 : if ( ! pContainer )
1863 137 : return;
1864 :
1865 58 : css::lang::EventObject aEvent( static_cast< ::cppu::OWeakObject* >(this) );
1866 :
1867 58 : ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
1868 122 : while ( aIterator.hasMoreElements() )
1869 : {
1870 : try
1871 : {
1872 64 : css::uno::Reference< css::frame::XTerminateListener > xListener(aIterator.next(), css::uno::UNO_QUERY);
1873 64 : if ( ! xListener.is() )
1874 0 : continue;
1875 64 : xListener->notifyTermination( aEvent );
1876 : }
1877 0 : catch( const css::uno::Exception& )
1878 : {
1879 : // clean up container.
1880 : // E.g. dead remote listener objects can make trouble otherwise.
1881 : // Iterator implementation allows removing objects during it's used !
1882 0 : aIterator.remove();
1883 : }
1884 29 : }
1885 : }
1886 :
1887 : //=============================================================================
1888 83 : ::sal_Bool Desktop::impl_closeFrames(::sal_Bool bAllowUI)
1889 : {
1890 83 : ReadGuard aReadLock( m_aLock ); // start synchronize
1891 166 : css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > lFrames = m_aChildTaskContainer.getAllElements();
1892 83 : aReadLock.unlock(); // end synchronize
1893 :
1894 83 : ::sal_Int32 c = lFrames.getLength();
1895 83 : ::sal_Int32 i = 0;
1896 83 : ::sal_Int32 nNonClosedFrames = 0;
1897 :
1898 86 : for( i=0; i<c; ++i )
1899 : {
1900 : try
1901 : {
1902 3 : css::uno::Reference< css::frame::XFrame > xFrame = lFrames[i];
1903 :
1904 : // XController.suspend() will show an UI ...
1905 : // Use it in case it was allowed from outside only.
1906 3 : sal_Bool bSuspended = sal_False;
1907 3 : css::uno::Reference< css::frame::XController > xController( xFrame->getController(), css::uno::UNO_QUERY );
1908 3 : if (
1909 6 : ( bAllowUI ) &&
1910 3 : ( xController.is() )
1911 : )
1912 : {
1913 3 : bSuspended = xController->suspend( sal_True );
1914 3 : if ( ! bSuspended )
1915 : {
1916 0 : ++nNonClosedFrames;
1917 0 : continue;
1918 : }
1919 : }
1920 :
1921 : // Try to close frame (in case no UI was allowed without calling XController->suspend() before!)
1922 : // But don't deliver ownership to any other one!
1923 : // This method can be called again.
1924 3 : css::uno::Reference< css::util::XCloseable > xClose( xFrame, css::uno::UNO_QUERY );
1925 3 : if ( xClose.is() )
1926 : {
1927 : try
1928 : {
1929 3 : xClose->close(sal_False);
1930 : }
1931 0 : catch(const css::util::CloseVetoException&)
1932 : {
1933 : // Any internal process of this frame disagree with our request.
1934 : // Safe this state but dont break these loop. Other frames has to be closed!
1935 0 : ++nNonClosedFrames;
1936 :
1937 : // Reactivate controller.
1938 : // It can happen that XController.suspend() returned true ... but a registered close listener
1939 : // throwed these veto exception. Then the controller has to be reactivated. Otherwise
1940 : // these document doesnt work any more.
1941 0 : if (
1942 0 : (bSuspended ) &&
1943 0 : (xController.is())
1944 : )
1945 0 : xController->suspend(sal_False);
1946 : }
1947 :
1948 : // If interface XClosable interface exists and was used ...
1949 : // it's not allowed to use XComponent->dispose() also !
1950 3 : continue;
1951 : }
1952 :
1953 : // XClosable not supported ?
1954 : // Then we have to dispose these frame hardly.
1955 0 : css::uno::Reference< css::lang::XComponent > xDispose( xFrame, css::uno::UNO_QUERY );
1956 0 : if ( xDispose.is() )
1957 0 : xDispose->dispose();
1958 :
1959 : // Don't remove these frame from our child container!
1960 : // A frame do it by itself inside close()/dispose() method.
1961 : }
1962 0 : catch(const css::lang::DisposedException&)
1963 : {
1964 : // Dispose frames are closed frames.
1965 : // So we can count it here .-)
1966 : }
1967 : }
1968 :
1969 166 : return (nNonClosedFrames < 1);
1970 : }
1971 :
1972 : //_________________________________________________________________________________________________________________
1973 : // debug methods
1974 : //_________________________________________________________________________________________________________________
1975 :
1976 : /*-----------------------------------------------------------------------------------------------------------------
1977 : The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
1978 : we return "sal_True". (otherwise sal_False) This mechanism is used to throw an ASSERT!
1979 : -----------------------------------------------------------------------------------------------------------------*/
1980 :
1981 : #ifdef ENABLE_ASSERTIONS
1982 :
1983 : //*****************************************************************************************************************
1984 : // We work with valid servicemanager only.
1985 : sal_Bool Desktop::implcp_ctor( const css::uno::Reference< css::uno::XComponentContext >& xContext )
1986 : {
1987 : return(
1988 : ( &xContext == NULL ) ||
1989 : ( xContext.is() == sal_False )
1990 : );
1991 : }
1992 :
1993 : //*****************************************************************************************************************
1994 : // We work with valid listener only.
1995 : sal_Bool Desktop::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
1996 : {
1997 : return(
1998 : ( &xListener == NULL ) ||
1999 : ( xListener.is() == sal_False )
2000 : );
2001 : }
2002 :
2003 : //*****************************************************************************************************************
2004 : // We work with valid listener only.
2005 : sal_Bool Desktop::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
2006 : {
2007 : return(
2008 : ( &xListener == NULL ) ||
2009 : ( xListener.is() == sal_False )
2010 : );
2011 : }
2012 :
2013 : #endif // #ifdef ENABLE_ASSERTIONS
2014 :
2015 402 : } // namespace framework
2016 :
2017 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|