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