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