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