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