Update ooo320-m1
[ooovba.git] / framework / source / dispatch / closedispatcher.cxx
blobb49c29e2c8c2d9bfff665c3ba655b08065cb61ec
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: closedispatcher.cxx,v $
10 * $Revision: 1.22 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 //_______________________________________________
35 // my own includes
36 #include <dispatch/closedispatcher.hxx>
37 #include <pattern/frame.hxx>
38 #include <threadhelp/readguard.hxx>
39 #include <threadhelp/writeguard.hxx>
40 #include <classes/framelistanalyzer.hxx>
41 #include <services.h>
42 #include <general.h>
44 //_______________________________________________
45 // interface includes
46 #include <com/sun/star/frame/XDesktop.hpp>
47 #include <com/sun/star/frame/XController.hpp>
48 #include <com/sun/star/frame/CommandGroup.hpp>
49 #include <com/sun/star/lang/DisposedException.hpp>
50 #include <com/sun/star/awt/XTopWindow.hpp>
51 #include <com/sun/star/document/XActionLockable.hpp>
52 #include "com/sun/star/beans/XFastPropertySet.hpp"
53 #include <toolkit/helper/vclunohelper.hxx>
55 //_______________________________________________
56 // includes of other projects
58 #include <vcl/window.hxx>
59 #include <vcl/svapp.hxx>
60 #include <vos/mutex.hxx>
61 #include <svtools/moduleoptions.hxx>
63 //_______________________________________________
64 // namespace
66 namespace framework{
68 #ifdef fpf
69 #error "Who uses \"fpf\" as define. It will overwrite my namespace alias ..."
70 #endif
71 namespace fpf = ::framework::pattern::frame;
73 //_______________________________________________
74 // non exported const
76 static ::rtl::OUString URL_CLOSEDOC = DECLARE_ASCII(".uno:CloseDoc" );
77 static ::rtl::OUString URL_CLOSEWIN = DECLARE_ASCII(".uno:CloseWin" );
78 static ::rtl::OUString URL_CLOSEFRAME = DECLARE_ASCII(".uno:CloseFrame");
80 //_______________________________________________
81 // declarations
83 DEFINE_XINTERFACE_4(CloseDispatcher ,
84 OWeakObject ,
85 DIRECT_INTERFACE(css::lang::XTypeProvider ),
86 DIRECT_INTERFACE(css::frame::XNotifyingDispatch ),
87 DIRECT_INTERFACE(css::frame::XDispatch ),
88 DIRECT_INTERFACE(css::frame::XDispatchInformationProvider))
90 // Note: XStatusListener is an implementation detail. Hide it for scripting!
91 DEFINE_XTYPEPROVIDER_4(CloseDispatcher ,
92 css::lang::XTypeProvider ,
93 css::frame::XDispatchInformationProvider,
94 css::frame::XNotifyingDispatch ,
95 css::frame::XDispatch )
97 //-----------------------------------------------
98 CloseDispatcher::CloseDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
99 const css::uno::Reference< css::frame::XFrame >& xFrame ,
100 const ::rtl::OUString& sTarget)
101 : ThreadHelpBase (&Application::GetSolarMutex() )
102 , ::cppu::OWeakObject( )
103 , m_xSMGR (xSMGR )
104 , m_aAsyncCallback (LINK( this, CloseDispatcher, impl_asyncCallback))
105 , m_lStatusListener (m_aLock.getShareableOslMutex() )
107 m_xCloseFrame = CloseDispatcher::static_impl_searchRightTargetFrame(xFrame, sTarget);
110 //-----------------------------------------------
111 CloseDispatcher::~CloseDispatcher()
115 //-----------------------------------------------
116 void SAL_CALL CloseDispatcher::dispatch(const css::util::URL& aURL ,
117 const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
118 throw(css::uno::RuntimeException)
120 dispatchWithNotification(aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
123 //-----------------------------------------------
124 css::uno::Sequence< sal_Int16 > SAL_CALL CloseDispatcher::getSupportedCommandGroups()
125 throw(css::uno::RuntimeException)
127 css::uno::Sequence< sal_Int16 > lGroups(2);
128 lGroups[0] = css::frame::CommandGroup::VIEW;
129 lGroups[1] = css::frame::CommandGroup::DOCUMENT;
130 return lGroups;
133 //-----------------------------------------------
134 css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL CloseDispatcher::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
135 throw(css::uno::RuntimeException)
137 if (nCommandGroup == css::frame::CommandGroup::VIEW)
139 /* Attention: Dont add .uno:CloseFrame here. Because its not realy
140 a configurable feature ... and further it does not have
141 a valid UIName entry inside the GenericCommands.xcu ... */
142 css::uno::Sequence< css::frame::DispatchInformation > lViewInfos(1);
143 lViewInfos[0].Command = URL_CLOSEWIN;
144 lViewInfos[0].GroupId = css::frame::CommandGroup::VIEW;
145 return lViewInfos;
147 else
148 if (nCommandGroup == css::frame::CommandGroup::DOCUMENT)
150 css::uno::Sequence< css::frame::DispatchInformation > lDocInfos(1);
151 lDocInfos[0].Command = URL_CLOSEDOC;
152 lDocInfos[0].GroupId = css::frame::CommandGroup::DOCUMENT;
153 return lDocInfos;
156 return css::uno::Sequence< css::frame::DispatchInformation >();
159 //-----------------------------------------------
160 void SAL_CALL CloseDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
161 const css::util::URL& /*aURL*/ )
162 throw(css::uno::RuntimeException)
166 //-----------------------------------------------
167 void SAL_CALL CloseDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
168 const css::util::URL& /*aURL*/ )
169 throw(css::uno::RuntimeException)
173 //-----------------------------------------------
174 void SAL_CALL CloseDispatcher::dispatchWithNotification(const css::util::URL& aURL ,
175 const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
176 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
177 throw(css::uno::RuntimeException)
179 // SAFE -> ----------------------------------
180 WriteGuard aWriteLock(m_aLock);
182 // This reference indicates, that we was already called before and
183 // our asynchronous process was not finished yet.
184 // We have to reject double calls. Otherwhise we risk,
185 // that we try to close an already closed resource ...
186 // And its no problem to do nothing then. The UI user will try it again, if
187 // non of these jobs was successfully.
188 if (m_xSelfHold.is())
190 aWriteLock.unlock();
191 // <- SAFE ------------------------------
193 implts_notifyResultListener(
194 xListener,
195 css::frame::DispatchResultState::DONTKNOW,
196 css::uno::Any());
197 return;
200 // First we have to check, if this dispatcher is used right. Means if valid URLs are used.
201 // If not - we have to break this operation. But an optional listener must be informed.
202 // BTW: We save the information about the requested operation. Because
203 // we need it later.
204 if (aURL.Complete.equals(URL_CLOSEDOC))
205 m_eOperation = E_CLOSE_DOC;
206 else
207 if (aURL.Complete.equals(URL_CLOSEWIN))
208 m_eOperation = E_CLOSE_WIN;
209 else
210 if (aURL.Complete.equals(URL_CLOSEFRAME))
211 m_eOperation = E_CLOSE_FRAME;
212 else
214 aWriteLock.unlock();
215 // <- SAFE ------------------------------
217 implts_notifyResultListener(
218 xListener,
219 css::frame::DispatchResultState::FAILURE,
220 css::uno::Any());
221 return;
224 // OK - URLs are the right ones.
225 // But we cant execute synchronously :-)
226 // May we are called from a generic key-input handler,
227 // which isnt aware that this call kill its own environment ...
228 // Do it asynchronous everytimes!
230 // But dont forget to hold usself alive.
231 // We are called back from an environment, which doesnt know an uno reference.
232 // They call us back by using our c++ interface.
234 m_xResultListener = xListener;
235 m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
237 aWriteLock.unlock();
238 // <- SAFE ----------------------------------
240 sal_Bool bIsSynchron = sal_False;
241 for (sal_Int32 nArgs=0; nArgs<lArguments.getLength(); nArgs++ )
243 if ( lArguments[nArgs].Name.equalsAscii("SynchronMode") )
245 lArguments[nArgs].Value >>= bIsSynchron;
246 break;
250 if ( bIsSynchron )
251 impl_asyncCallback(0);
252 else
253 m_aAsyncCallback.Post(0);
256 //-----------------------------------------------
258 @short asynchronous callback
259 @descr We start all actions inside this object asnychronoue.
260 (see comments there).
261 Now we do the following:
262 - close all views to the same document, if needed and possible
263 - make the current frame empty
264 ! This step is neccessary to handle errors during closing the
265 document inside the frame. May the document shows a dialog and
266 the user ignore it. Then the state of the office can be changed
267 during we try to close frame and document.
268 - check the environment (menas count open frames - exlcuding our
269 current one)
270 - decide then, if we must close this frame only, establish the backing mode
271 or shutdown the whole application.
273 IMPL_LINK( CloseDispatcher, impl_asyncCallback, void*, EMPTYARG )
278 // Allow calling of XController->suspend() everytimes.
279 // Dispatch is an UI functionality. We implement such dispatch object here.
280 // And further XController->suspend() was designed to bring an UI ...
281 sal_Bool bAllowSuspend = sal_True;
282 sal_Bool bControllerSuspended = sal_False;
284 // SAFE -> ----------------------------------
285 ReadGuard aReadLock(m_aLock);
287 // Closing of all views, related to the same document, is allowed
288 // only if the dispatched URL was ".uno:CloseDoc"!
289 sal_Bool bCloseAllViewsToo = (m_eOperation == E_CLOSE_DOC);
291 // BTW: Make some copies, which are needed later ...
292 EOperation eOperation = m_eOperation;
293 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
294 css::uno::Reference< css::frame::XFrame > xCloseFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
295 css::uno::Reference< css::frame::XDispatchResultListener > xListener = m_xResultListener;
297 aReadLock.unlock();
298 // <- SAFE ----------------------------------
300 // frame already dead ?!
301 // Nothing to do !
302 if (! xCloseFrame.is())
303 return 0;
305 sal_Bool bCloseFrame = sal_False;
306 sal_Bool bEstablishBackingMode = sal_False;
307 sal_Bool bTerminateApp = sal_False;
309 // Analyze the environment a first time.
310 // If we found some special cases, we can
311 // make some decisions erliar!
312 css::uno::Reference< css::frame::XFramesSupplier > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
313 FrameListAnalyzer aCheck1(xDesktop, xCloseFrame, FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
315 // a) If the curent frame (where the close dispatch was requested for) does not have
316 // any parent frame ... it will close this frame only. Such frame isnt part of the
317 // global desktop tree ... and such frames are used as "implementation details" only.
318 // E.g. the live previews of our wizards doing such things. And then the owner of the frame
319 // is responsible for closing the application or accepting closing of the application
320 // by others.
321 if ( ! xCloseFrame->getCreator().is())
322 bCloseFrame = sal_True;
323 else
325 // b) The help window cant disagree with any request.
326 // Because it doesnt implement a controller - it uses a window only.
327 // Further t cant be the last open frame - if we do all other things
328 // right inside this CloseDispatcher implementation.
329 // => close it!
330 if (aCheck1.m_bReferenceIsHelp)
331 bCloseFrame = sal_True;
332 else
334 // c) If we are already in "backing mode", we have to terminate
335 // the application, if this special frame is closed.
336 // It doesnt matter, how many other frames (can be the help or hidden frames only)
337 // are open then.
338 // => terminate the application!
339 if (aCheck1.m_bReferenceIsBacking)
340 bTerminateApp = sal_True;
341 else
343 // d) Otherwhise we have to: close all views to the same document, close the
344 // document inside our own frame and decide then again, what has to be done!
346 if (implts_prepareFrameForClosing(m_xCloseFrame, bAllowSuspend, bCloseAllViewsToo, bControllerSuspended))
348 // OK; this frame is empty now.
349 // Check the environment again to decide, what is the next step.
350 FrameListAnalyzer aCheck2(xDesktop, xCloseFrame, FrameListAnalyzer::E_ALL);
352 // c1) there is as minimum 1 frame open, which is visible and contains a document
353 // different from our one. And its not the help!
354 // => close our frame only - nothing else.
355 if (aCheck2.m_lOtherVisibleFrames.getLength()>0)
356 bCloseFrame = sal_True;
357 else
359 // c2) if we close the current view ... but not all other views
360 // to the same document, we must close the current frame only!
361 // Because implts_closeView() suspended this view only - does not
362 // close the frame.
363 if (
364 (!bCloseAllViewsToo ) &&
365 (aCheck2.m_lModelFrames.getLength() > 0)
367 bCloseFrame = sal_True;
369 else
370 // c3) there is no other (visible) frame open ...
371 // The help module will be ignored everytimes!
372 // But we have to decide if we must terminate the
373 // application or establish the backing mode now.
374 // And that depends from the dispatched URL ...
376 if (eOperation == E_CLOSE_FRAME)
377 bTerminateApp = sal_True;
378 else if( SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE) )
379 bEstablishBackingMode = sal_True;
380 else
381 bTerminateApp = sal_True;
386 // Do it now ...
387 sal_Bool bSuccess = sal_False;
388 if (bCloseFrame)
389 bSuccess = implts_closeFrame();
390 else
391 if (bEstablishBackingMode)
392 #if defined QUARTZ
394 // on mac close down, quickstarter keeps the process alive
395 // however if someone has shut down the quickstarter
396 // behave as any other platform
398 bool bQuickstarterRunning = false;
399 // get quickstart service
402 css::uno::Reference< css::beans::XFastPropertySet > xSet( xSMGR->createInstance(IMPLEMENTATIONNAME_QUICKLAUNCHER), css::uno::UNO_QUERY_THROW );
403 if( xSet.is() )
405 css::uno::Any aVal( xSet->getFastPropertyValue( 0 ) );
406 sal_Bool bState = sal_False;
407 if( aVal >>= bState )
408 bQuickstarterRunning = bState;
411 catch( css::uno::Exception& )
414 bSuccess = bQuickstarterRunning ? implts_terminateApplication() : implts_establishBackingMode();
416 #else
417 bSuccess = implts_establishBackingMode();
418 #endif
419 else
420 if (bTerminateApp)
421 bSuccess = implts_terminateApplication();
423 if (
424 ( ! bSuccess ) &&
425 ( bControllerSuspended )
428 css::uno::Reference< css::frame::XController > xController = xCloseFrame->getController();
429 if (xController.is())
430 xController->suspend(sal_False);
433 // inform listener
434 sal_Int16 nState = css::frame::DispatchResultState::FAILURE;
435 if (bSuccess)
436 nState = css::frame::DispatchResultState::SUCCESS;
437 implts_notifyResultListener(xListener, nState, css::uno::Any());
439 // SAFE -> ----------------------------------
440 WriteGuard aWriteLock(m_aLock);
442 // This method was called asynchronous from our main thread by using a pointer.
443 // We reached this method only, by using a reference to ourself :-)
444 // Further this member is used to detect still running and not yet finished
445 // ansynchronous operations. So its time now to release this reference.
446 // But hold it temp alive. Otherwhise we die before we can finish this method realy :-))
447 css::uno::Reference< css::uno::XInterface > xTempHold = m_xSelfHold;
448 m_xSelfHold.clear();
449 m_xResultListener.clear();
451 aWriteLock.unlock();
452 // <- SAFE ----------------------------------
455 catch(const css::lang::DisposedException&)
457 LOG_ERROR("CloseDispatcher::impl_asyncCallback", "Congratulation! You found the reason for bug #120310#. Please contact the right developer and show him a scenario, which trigger this bug. THX.")
460 return 0;
463 //-----------------------------------------------
464 sal_Bool CloseDispatcher::implts_prepareFrameForClosing(const css::uno::Reference< css::frame::XFrame >& xFrame ,
465 sal_Bool bAllowSuspend ,
466 sal_Bool bCloseAllOtherViewsToo,
467 sal_Bool& bControllerSuspended )
469 // Frame already dead ... so this view is closed ... is closed ... is ... .-)
470 if (! xFrame.is())
471 return sal_True;
473 // Close all views to the same document ... if forced to do so.
474 // But dont touch our own frame here!
475 // We must do so ... because the may be following controller->suspend()
476 // will show the "save/discard/cancel" dialog for the last view only!
477 if (bCloseAllOtherViewsToo)
479 // SAFE -> ----------------------------------
480 ReadGuard aReadLock(m_aLock);
481 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
482 aReadLock.unlock();
483 // <- SAFE ----------------------------------
485 css::uno::Reference< css::frame::XFramesSupplier > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
486 FrameListAnalyzer aCheck(xDesktop, xFrame, FrameListAnalyzer::E_ALL);
488 sal_Int32 c = aCheck.m_lModelFrames.getLength();
489 sal_Int32 i = 0;
490 for (i=0; i<c; ++i)
492 if (!fpf::closeIt(aCheck.m_lModelFrames[i], sal_False))
493 return sal_False;
497 // If allowed - inform user about modified documents or
498 // still running jobs (e.g. printing).
499 if (bAllowSuspend)
501 css::uno::Reference< css::frame::XController > xController = xFrame->getController();
502 if (xController.is()) // some views dont uses a controller .-( (e.g. the help window)
504 bControllerSuspended = xController->suspend(sal_True);
505 if (! bControllerSuspended)
506 return sal_False;
510 // dont remove the component realy by e.g. calling setComponent(null, null).
511 // It's enough to suspend the controller.
512 // If we close the frame later this controller doesnt show the same dialog again.
513 return sal_True;
516 //-----------------------------------------------
517 sal_Bool CloseDispatcher::implts_closeFrame()
519 // SAFE -> ----------------------------------
520 ReadGuard aReadLock(m_aLock);
521 css::uno::Reference< css::frame::XFrame > xFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
522 aReadLock.unlock();
523 // <- SAFE ----------------------------------
525 // frame already dead ? => so it's closed ... it's closed ...
526 if ( ! xFrame.is() )
527 return sal_True;
529 // dont deliver owner ship; our "UI user" will try it again if it failed.
530 // OK - he will get an empty frame then. But normaly an empty frame
531 // should be closeable always :-)
532 if (!fpf::closeIt(xFrame, sal_False))
533 return sal_False;
535 // SAFE -> ----------------------------------
536 WriteGuard aWriteLock(m_aLock);
537 m_xCloseFrame = css::uno::WeakReference< css::frame::XFrame >();
538 aWriteLock.unlock();
539 // <- SAFE ----------------------------------
541 return sal_True;
544 //-----------------------------------------------
545 sal_Bool CloseDispatcher::implts_establishBackingMode()
547 // SAFE -> ----------------------------------
548 ReadGuard aReadLock(m_aLock);
549 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
550 css::uno::Reference< css::frame::XFrame > xFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
551 aReadLock.unlock();
552 // <- SAFE ----------------------------------
554 if (!xFrame.is())
555 return sal_False;
557 css::uno::Reference < css::document::XActionLockable > xLock( xFrame, css::uno::UNO_QUERY );
558 if ( xLock.is() && xLock->isActionLocked() )
559 return sal_False;
561 css::uno::Reference< css::awt::XWindow > xContainerWindow = xFrame->getContainerWindow();
562 css::uno::Sequence< css::uno::Any > lArgs(1);
563 lArgs[0] <<= xContainerWindow;
565 css::uno::Reference< css::frame::XController > xBackingComp(
566 xSMGR->createInstanceWithArguments(SERVICENAME_STARTMODULE, lArgs),
567 css::uno::UNO_QUERY_THROW);
569 // Attention: You MUST(!) call setComponent() before you call attachFrame().
570 css::uno::Reference< css::awt::XWindow > xBackingWin(xBackingComp, css::uno::UNO_QUERY);
571 xFrame->setComponent(xBackingWin, xBackingComp);
572 xBackingComp->attachFrame(xFrame);
573 xContainerWindow->setVisible(sal_True);
575 return sal_True;
578 //-----------------------------------------------
579 sal_Bool CloseDispatcher::implts_terminateApplication()
581 // SAFE -> ----------------------------------
582 ReadGuard aReadLock(m_aLock);
583 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
584 aReadLock.unlock();
585 // <- SAFE ----------------------------------
587 css::uno::Reference< css::frame::XDesktop > xDesktop(
588 xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
590 return xDesktop->terminate();
593 //-----------------------------------------------
594 void CloseDispatcher::implts_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener >& xListener,
595 sal_Int16 nState ,
596 const css::uno::Any& aResult )
598 if (!xListener.is())
599 return;
601 css::frame::DispatchResultEvent aEvent(
602 css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY),
603 nState,
604 aResult);
606 xListener->dispatchFinished(aEvent);
609 //-----------------------------------------------
610 css::uno::Reference< css::frame::XFrame > CloseDispatcher::static_impl_searchRightTargetFrame(const css::uno::Reference< css::frame::XFrame >& xFrame ,
611 const ::rtl::OUString& sTarget)
613 if (sTarget.equalsIgnoreAsciiCaseAscii("_self"))
614 return xFrame;
616 OSL_ENSURE((sTarget.getLength() < 1), "CloseDispatch used for unexpected target. Magic things will happen now .-)");
618 css::uno::Reference< css::frame::XFrame > xTarget = xFrame;
619 while(sal_True)
621 // a) top frames wil be closed
622 if (xTarget->isTop())
623 return xTarget;
625 // b) even child frame containing top level windows (e.g. query designer of database) will be closed
626 css::uno::Reference< css::awt::XWindow > xWindow = xTarget->getContainerWindow();
627 css::uno::Reference< css::awt::XTopWindow > xTopWindowCheck(xWindow, css::uno::UNO_QUERY);
628 if (xTopWindowCheck.is())
630 // b1) Note: Toolkit interface XTopWindow sometimes is used by real VCL-child-windows also .-)
631 // Be sure that these window is realy a "top system window".
632 // Attention ! Checking Window->GetParent() isnt the right approach here.
633 // Because sometimes VCL create "implicit border windows" as parents even we created
634 // a simple XWindow using the toolkit only .-(
635 ::vos::OGuard aSolarLock(&Application::GetSolarMutex());
636 Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
637 if (
638 (pWindow ) &&
639 (pWindow->IsSystemWindow())
641 return xTarget;
644 // c) try to find better results on parent frame
645 // If no parent frame exists (because this frame is used outside the desktop tree)
646 // the given frame must be used directly.
647 css::uno::Reference< css::frame::XFrame > xParent(xTarget->getCreator(), css::uno::UNO_QUERY);
648 if ( ! xParent.is())
649 return xTarget;
651 // c1) check parent frame inside next loop ...
652 xTarget = xParent;
656 } // namespace framework