LibreOffice Module framework (master) 1
closedispatcher.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21#include <pattern/frame.hxx>
23#include <services.h>
24
25#include <com/sun/star/bridge/BridgeFactory.hpp>
26#include <com/sun/star/bridge/XBridgeFactory2.hpp>
27#include <com/sun/star/frame/Desktop.hpp>
28#include <com/sun/star/frame/DispatchResultState.hpp>
29#include <com/sun/star/frame/XController.hpp>
30#include <com/sun/star/frame/CommandGroup.hpp>
31#include <com/sun/star/frame/StartModule.hpp>
32#include <com/sun/star/lang/DisposedException.hpp>
33#include <com/sun/star/awt/XTopWindow.hpp>
34#include <com/sun/star/document/XActionLockable.hpp>
35#include <com/sun/star/beans/XFastPropertySet.hpp>
37
38#include <osl/diagnose.h>
39#include <utility>
40#include <vcl/window.hxx>
41#include <vcl/svapp.hxx>
42#include <vcl/syswin.hxx>
44#include <o3tl/string_view.hxx>
45
46using namespace com::sun::star;
47
48namespace framework{
49
50#ifdef fpf
51 #error "Who uses \"fpf\" as define. It will overwrite my namespace alias ..."
52#endif
53namespace fpf = ::framework::pattern::frame;
54
55constexpr OUStringLiteral URL_CLOSEDOC = u".uno:CloseDoc";
56constexpr OUStringLiteral URL_CLOSEWIN = u".uno:CloseWin";
57const char URL_CLOSEFRAME[] = ".uno:CloseFrame";
58
59CloseDispatcher::CloseDispatcher(css::uno::Reference< css::uno::XComponentContext > xContext ,
60 const css::uno::Reference< css::frame::XFrame >& xFrame ,
61 std::u16string_view sTarget)
62 : m_xContext(std::move(xContext))
64 new vcl::EventPoster(LINK(this, CloseDispatcher, impl_asyncCallback)))
65 , m_eOperation(E_CLOSE_DOC)
66 , m_pSysWindow(nullptr)
67{
68 uno::Reference<frame::XFrame> xTarget = static_impl_searchRightTargetFrame(xFrame, sTarget);
70
71 // Try to retrieve the system window instance of the closing frame.
72 uno::Reference<awt::XWindow> xWindow = xTarget->getContainerWindow();
73 if (xWindow.is())
74 {
76 if (pWindow->IsSystemWindow())
77 m_pSysWindow = dynamic_cast<SystemWindow*>(pWindow.get());
78 }
79}
80
82{
84 m_aAsyncCallback.reset();
86}
87
88void SAL_CALL CloseDispatcher::dispatch(const css::util::URL& aURL ,
89 const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
90{
91 dispatchWithNotification(aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
92}
93
94css::uno::Sequence< sal_Int16 > SAL_CALL CloseDispatcher::getSupportedCommandGroups()
95{
96 return css::uno::Sequence< sal_Int16 >{css::frame::CommandGroup::VIEW, css::frame::CommandGroup::DOCUMENT};
97}
98
99css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL CloseDispatcher::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
100{
101 if (nCommandGroup == css::frame::CommandGroup::VIEW)
102 {
103 /* Attention: Don't add .uno:CloseFrame here. Because it's not really
104 a configurable feature ... and further it does not have
105 a valid UIName entry inside the GenericCommands.xcu ... */
106 css::uno::Sequence< css::frame::DispatchInformation > lViewInfos{
107 { URL_CLOSEWIN, css::frame::CommandGroup::VIEW }
108 };
109 return lViewInfos;
110 }
111 else if (nCommandGroup == css::frame::CommandGroup::DOCUMENT)
112 {
113 css::uno::Sequence< css::frame::DispatchInformation > lDocInfos{
114 { URL_CLOSEDOC, css::frame::CommandGroup::DOCUMENT }
115 };
116 return lDocInfos;
117 }
118
119 return css::uno::Sequence< css::frame::DispatchInformation >();
120}
121
122void SAL_CALL CloseDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
123 const css::util::URL& /*aURL*/ )
124{
125}
126
127void SAL_CALL CloseDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
128 const css::util::URL& /*aURL*/ )
129{
130}
131
132void SAL_CALL CloseDispatcher::dispatchWithNotification(const css::util::URL& aURL ,
133 const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
134 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
135{
136 // SAFE -> ----------------------------------
137 SolarMutexClearableGuard aWriteLock;
138
139 // This reference indicates, that we were already called before and
140 // our asynchronous process was not finished yet.
141 // We have to reject double calls. Otherwise we risk,
142 // that we try to close an already closed resource...
143 // And it is no problem to do nothing then. The UI user will try it again, if
144 // non of these jobs was successful.
145 if (m_xSelfHold.is())
146 {
147 aWriteLock.clear();
148 // <- SAFE ------------------------------
149
151 xListener,
152 css::frame::DispatchResultState::DONTKNOW,
153 css::uno::Any());
154 return;
155 }
156
157 // First we have to check, if this dispatcher is used right. Means if valid URLs are used.
158 // If not - we have to break this operation. But an optional listener must be informed.
159 // BTW: We save the information about the requested operation. Because
160 // we need it later.
161 if ( aURL.Complete == URL_CLOSEDOC )
163 else if ( aURL.Complete == URL_CLOSEWIN )
165 else if ( aURL.Complete == URL_CLOSEFRAME )
167 else
168 {
169 aWriteLock.clear();
170 // <- SAFE ------------------------------
171
173 xListener,
174 css::frame::DispatchResultState::FAILURE,
175 css::uno::Any());
176 return;
177 }
178
179 if (m_pSysWindow && m_pSysWindow->GetCloseHdl().IsSet())
180 {
181 // The closing frame has its own close handler. Call it instead.
182 m_pSysWindow->GetCloseHdl().Call(*m_pSysWindow);
183
184 aWriteLock.clear();
185 // <- SAFE ------------------------------
186
188 xListener,
189 css::frame::DispatchResultState::SUCCESS,
190 css::uno::Any());
191
192 return;
193 }
194
195 // OK - URLs are the right ones.
196 // But we can't execute synchronously :-)
197 // May we are called from a generic key-input handler,
198 // which isn't aware that this call kill its own environment...
199 // Do it asynchronous everytimes!
200
201 // But don't forget to hold ourselves alive.
202 // We are called back from an environment, which doesn't know a uno reference.
203 // They call us back by using our c++ interface.
204
205 m_xResultListener = xListener;
206 m_xSelfHold.set(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
207
208 aWriteLock.clear();
209 // <- SAFE ----------------------------------
210
211 bool bIsSynchron = false;
212 for (const css::beans::PropertyValue& rArg : lArguments )
213 {
214 if ( rArg.Name == "SynchronMode" )
215 {
216 rArg.Value >>= bIsSynchron;
217 break;
218 }
219 }
220
221 if ( bIsSynchron )
222 impl_asyncCallback(nullptr);
223 else
224 {
226 m_aAsyncCallback->Post();
227 }
228}
229
247{
248 try
249 {
250
251 // Allow calling of XController->suspend() everytimes.
252 // Dispatch is an UI functionality. We implement such dispatch object here.
253 // And further XController->suspend() was designed to bring an UI ...
254 bool bControllerSuspended = false;
255
256 bool bCloseAllViewsToo;
257 EOperation eOperation;
258 css::uno::Reference< css::uno::XComponentContext > xContext;
259 css::uno::Reference< css::frame::XFrame > xCloseFrame;
260 css::uno::Reference< css::frame::XDispatchResultListener > xListener;
261 {
263
264 // Closing of all views, related to the same document, is allowed
265 // only if the dispatched URL was ".uno:CloseDoc"!
266 bCloseAllViewsToo = (m_eOperation == E_CLOSE_DOC);
267
268 eOperation = m_eOperation;
269 xContext = m_xContext;
270 xCloseFrame.set(m_xCloseFrame.get(), css::uno::UNO_QUERY);
271 xListener = m_xResultListener;
272 }
273
274 // frame already dead ?!
275 // Nothing to do !
276 if (! xCloseFrame.is())
277 return;
278
279 bool bCloseFrame = false;
280 bool bEstablishBackingMode = false;
281 bool bTerminateApp = false;
282
283 // Analyze the environment a first time.
284 // If we found some special cases, we can
285 // make some decisions earlier!
286 css::uno::Reference< css::frame::XFramesSupplier > xDesktop( css::frame::Desktop::create(xContext), css::uno::UNO_QUERY_THROW);
287 FrameListAnalyzer aCheck1(xDesktop, xCloseFrame, FrameAnalyzerFlags::Help | FrameAnalyzerFlags::BackingComponent);
288
289 // Check for existing UNO connections.
290 // NOTE: There is a race between checking this and connections being created/destroyed before
291 // we close the frame / terminate the app.
292 css::uno::Reference<css::bridge::XBridgeFactory2> bridgeFac( css::bridge::BridgeFactory::create(xContext) );
293 bool bHasActiveConnections = bridgeFac->getExistingBridges().hasElements();
294
295 // a) If the current frame (where the close dispatch was requested for) does not have
296 // any parent frame ... it will close this frame only. Such frame isn't part of the
297 // global desktop tree ... and such frames are used as "implementation details" only.
298 // E.g. the live previews of our wizards doing such things. And then the owner of the frame
299 // is responsible for closing the application or accepting closing of the application
300 // by others.
301 if ( ! xCloseFrame->getCreator().is())
302 bCloseFrame = true;
303
304 // b) The help window can't disagree with any request.
305 // Because it doesn't implement a controller - it uses a window only.
306 // Further it can't be the last open frame - if we do all other things
307 // right inside this CloseDispatcher implementation.
308 // => close it!
309 else if (aCheck1.m_bReferenceIsHelp)
310 bCloseFrame = true;
311
312 // c) If we are already in "backing mode", we terminate the application, if no active UNO connections are found.
313 // If there is an active UNO connection, we only close the frame and leave the application alive.
314 // It doesn't matter, how many other frames (can be the help or hidden frames only) are open then.
315 else if (aCheck1.m_bReferenceIsBacking) {
316 if (bHasActiveConnections)
317 bCloseFrame = true;
318 else
319 bTerminateApp = true;
320 }
321
322 // d) Otherwise we have to: close all views to the same document, close the
323 // document inside our own frame and decide then again, what has to be done!
324 else
325 {
326 if (implts_prepareFrameForClosing(m_xCloseFrame, bCloseAllViewsToo, bControllerSuspended))
327 {
328 // OK; this frame is empty now.
329 // Check the environment again to decide, what is the next step.
330 FrameListAnalyzer aCheck2(xDesktop, xCloseFrame, FrameAnalyzerFlags::All);
331
332 // c1) there is as minimum 1 frame open, which is visible and contains a document
333 // different from our one. And it's not the help!
334 // (tdf#30920 consider that closing a frame which is not the backing window (start center) while there is
335 // another frame that is the backing window open only closes the frame, and not terminate the app, so
336 // closing the license frame doesn't terminate the app if launched from the start center)
337 // => close our frame only - nothing else.
338 if (!aCheck2.m_lOtherVisibleFrames.empty() || (!aCheck2.m_bReferenceIsBacking && aCheck2.m_xBackingComponent.is()))
339 bCloseFrame = true;
340 else
341
342 // c2) if we close the current view ... but not all other views
343 // to the same document, we must close the current frame only!
344 // Because implts_closeView() suspended this view only - does not
345 // close the frame.
346 if (
347 (!bCloseAllViewsToo ) &&
348 (!aCheck2.m_lModelFrames.empty())
349 )
350 bCloseFrame = true;
351
352 else
353 // c3) there is no other (visible) frame open ...
354 // The help module will be ignored everytimes!
355 // But we have to decide if we must terminate the
356 // application or establish the backing mode now.
357 // And that depends from the dispatched URL ...
358 {
359 if (eOperation == E_CLOSE_FRAME)
360 {
361 if (bHasActiveConnections)
362 bCloseFrame = true;
363 else
364 bTerminateApp = true;
365 }
366 else if( SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::STARTMODULE) )
367 bEstablishBackingMode = true;
368 else if (bHasActiveConnections)
369 bCloseFrame = true;
370 else
371 bTerminateApp = true;
372 }
373 }
374 }
375
376 // Do it now ...
377 bool bSuccess = false;
378 if (bCloseFrame)
379 bSuccess = implts_closeFrame();
380 else if (bEstablishBackingMode)
381 #if defined MACOSX
382 {
383 // on mac close down, quickstarter keeps the process alive
384 // however if someone has shut down the quickstarter
385 // behave as any other platform
386
387 bool bQuickstarterRunning = false;
388 // get quickstart service
389 try
390 {
391 css::uno::Reference< css::beans::XFastPropertySet > xSet( xContext->getServiceManager()->createInstanceWithContext(IMPLEMENTATIONNAME_QUICKLAUNCHER, xContext), css::uno::UNO_QUERY_THROW );
392 css::uno::Any aVal( xSet->getFastPropertyValue( 0 ) );
393 bool bState = false;
394 if( aVal >>= bState )
395 bQuickstarterRunning = bState;
396 }
397 catch( const css::uno::Exception& )
398 {
399 }
400 bSuccess = bQuickstarterRunning ? implts_terminateApplication() : implts_establishBackingMode();
401 }
402 #else
403 bSuccess = implts_establishBackingMode();
404 #endif
405 else if (bTerminateApp)
406 bSuccess = implts_terminateApplication();
407
408 if ( ! bSuccess && bControllerSuspended )
409 {
410 css::uno::Reference< css::frame::XController > xController = xCloseFrame->getController();
411 if (xController.is())
412 xController->suspend(false);
413 }
414
415 // inform listener
416 sal_Int16 nState = css::frame::DispatchResultState::FAILURE;
417 if (bSuccess)
418 nState = css::frame::DispatchResultState::SUCCESS;
419 implts_notifyResultListener(xListener, nState, css::uno::Any());
420
422 // This method was called asynchronous from our main thread by using a pointer.
423 // We reached this method only, by using a reference to ourself :-)
424 // Further this member is used to detect still running and not yet finished
425 // asynchronous operations. So it's time now to release this reference.
426 // But hold it temp alive. Otherwise we die before we can finish this method really :-))
427 css::uno::Reference< css::uno::XInterface > xTempHold = m_xSelfHold;
428 m_xSelfHold.clear();
429 m_xResultListener.clear();
430 }
431 catch(const css::lang::DisposedException&)
432 {
433 }
434}
435
436bool CloseDispatcher::implts_prepareFrameForClosing(const css::uno::Reference< css::frame::XFrame >& xFrame,
437 bool bCloseAllOtherViewsToo,
438 bool& bControllerSuspended )
439{
440 // Frame already dead ... so this view is closed ... is closed ... is ... .-)
441 if (! xFrame.is())
442 return true;
443
444 // Close all views to the same document ... if forced to do so.
445 // But don't touch our own frame here!
446 // We must do so ... because the may be following controller->suspend()
447 // will show the "save/discard/cancel" dialog for the last view only!
448 if (bCloseAllOtherViewsToo)
449 {
450 css::uno::Reference< css::uno::XComponentContext > xContext;
451 {
453 xContext = m_xContext;
454 }
455
456 css::uno::Reference< css::frame::XFramesSupplier > xDesktop( css::frame::Desktop::create( xContext ), css::uno::UNO_QUERY_THROW);
457 FrameListAnalyzer aCheck(xDesktop, xFrame, FrameAnalyzerFlags::All);
458
459 size_t c = aCheck.m_lModelFrames.size();
460 size_t i = 0;
461 for (i=0; i<c; ++i)
462 {
463 if (!fpf::closeIt(aCheck.m_lModelFrames[i]))
464 return false;
465 }
466 }
467
468 // Inform user about modified documents or still running jobs (e.g. printing).
469 {
470 css::uno::Reference< css::frame::XController > xController = xFrame->getController();
471 if (xController.is()) // some views don't uses a controller .-( (e.g. the help window)
472 {
473 bControllerSuspended = xController->suspend(true);
474 if (! bControllerSuspended)
475 return false;
476 }
477 }
478
479 // don't remove the component really by e.g. calling setComponent(null, null).
480 // It's enough to suspend the controller.
481 // If we close the frame later this controller doesn't show the same dialog again.
482 return true;
483}
484
486{
487 css::uno::Reference< css::frame::XFrame > xFrame;
488 {
490 xFrame.set(m_xCloseFrame.get(), css::uno::UNO_QUERY);
491 }
492
493 // frame already dead ? => so it's closed ... it's closed ...
494 if ( ! xFrame.is() )
495 return true;
496
497 // don't deliver ownership; our "UI user" will try it again if it failed.
498 // OK - he will get an empty frame then. But normally an empty frame
499 // should be closeable always :-)
500 if (!fpf::closeIt(xFrame))
501 return false;
502
503 {
505 m_xCloseFrame.clear();
506 }
507
508 return true;
509}
510
512{
513 css::uno::Reference< css::uno::XComponentContext > xContext;
514 css::uno::Reference< css::frame::XFrame > xFrame;
515 {
517 xContext = m_xContext;
518 xFrame.set(m_xCloseFrame.get(), css::uno::UNO_QUERY);
519 }
520
521 if (!xFrame.is())
522 return false;
523
524 css::uno::Reference < css::document::XActionLockable > xLock( xFrame, css::uno::UNO_QUERY );
525 if ( xLock.is() && xLock->isActionLocked() )
526 return false;
527
528 css::uno::Reference< css::awt::XWindow > xContainerWindow = xFrame->getContainerWindow();
529
530 css::uno::Reference< css::frame::XController > xStartModule = css::frame::StartModule::createWithParentWindow(
531 xContext, xContainerWindow);
532
533 // Attention: You MUST(!) call setComponent() before you call attachFrame().
534 css::uno::Reference< css::awt::XWindow > xBackingWin(xStartModule, css::uno::UNO_QUERY);
535 xFrame->setComponent(xBackingWin, xStartModule);
536 xStartModule->attachFrame(xFrame);
537 xContainerWindow->setVisible(true);
538
539 return true;
540}
541
543{
544 css::uno::Reference< css::uno::XComponentContext > xContext;
545 {
547 xContext = m_xContext;
548 }
549
550 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
551
552 return xDesktop->terminate();
553}
554
555void CloseDispatcher::implts_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener >& xListener,
556 sal_Int16 nState ,
557 const css::uno::Any& aResult )
558{
559 if (!xListener.is())
560 return;
561
562 css::frame::DispatchResultEvent aEvent(
563 css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY),
564 nState,
565 aResult);
566
567 xListener->dispatchFinished(aEvent);
568}
569
570css::uno::Reference< css::frame::XFrame > CloseDispatcher::static_impl_searchRightTargetFrame(const css::uno::Reference< css::frame::XFrame >& xFrame ,
571 std::u16string_view sTarget)
572{
573 if (o3tl::equalsIgnoreAsciiCase(sTarget, u"_self"))
574 return xFrame;
575
576 OSL_ENSURE(sTarget.empty(), "CloseDispatch used for unexpected target. Magic things will happen now .-)");
577
578 css::uno::Reference< css::frame::XFrame > xTarget = xFrame;
579 while(true)
580 {
581 // a) top frames will be closed
582 if (xTarget->isTop())
583 return xTarget;
584
585 // b) even child frame containing top level windows (e.g. query designer of database) will be closed
586 css::uno::Reference< css::awt::XWindow > xWindow = xTarget->getContainerWindow();
587 css::uno::Reference< css::awt::XTopWindow > xTopWindowCheck(xWindow, css::uno::UNO_QUERY);
588 if (xTopWindowCheck.is())
589 {
590 // b1) Note: Toolkit interface XTopWindow sometimes is used by real VCL-child-windows also .-)
591 // Be sure that these window is really a "top system window".
592 // Attention ! Checking Window->GetParent() isn't the right approach here.
593 // Because sometimes VCL create "implicit border windows" as parents even we created
594 // a simple XWindow using the toolkit only .-(
595 SolarMutexGuard aSolarLock;
596 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
597 if ( pWindow && pWindow->IsSystemWindow() )
598 return xTarget;
599 }
600
601 // c) try to find better results on parent frame
602 // If no parent frame exists (because this frame is used outside the desktop tree)
603 // the given frame must be used directly.
604 css::uno::Reference< css::frame::XFrame > xParent = xTarget->getCreator();
605 if ( ! xParent.is())
606 return xTarget;
607
608 // c1) check parent frame inside next loop ...
609 xTarget = xParent;
610 }
611}
612
613} // namespace framework
614
615/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl::EventPoster m_aAsyncCallback
AnyEventRef aEvent
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
void reset(reference_type *pBody)
reference_type * get() const
helper to dispatch the URLs ".uno:CloseDoc"/".uno:CloseWin"/".uno:CloseFrame" to close a frame/docume...
virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedCommandGroups() override
virtual ~CloseDispatcher() override
does nothing real.
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xListener, const css::util::URL &aURL) override
bool implts_prepareFrameForClosing(const css::uno::Reference< css::frame::XFrame > &xFrame, bool bCloseAllOtherViewsToo, bool &bControllerSuspended)
prepare m_xCloseFrame so it should be closeable without problems.
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xListener, const css::util::URL &aURL) override
bool implts_terminateApplication()
calls XDesktop->terminate().
std::unique_ptr< vcl::EventPoster > m_aAsyncCallback
used for asynchronous callbacks within the main thread.
css::uno::Reference< css::uno::XComponentContext > m_xContext
reference to a uno service manager, which can be used to create own needed uno resources.
css::uno::Reference< css::uno::XInterface > m_xSelfHold
for asynchronous operations we must hold us self alive!
void implts_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener > &xListener, sal_Int16 nState, const css::uno::Any &aResult)
notify a DispatchResultListener.
virtual css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL getConfigurableDispatchInformation(sal_Int16 nCommandGroup) override
virtual void SAL_CALL dispatchWithNotification(const css::util::URL &aURL, const css::uno::Sequence< css::beans::PropertyValue > &lArguments, const css::uno::Reference< css::frame::XDispatchResultListener > &xListener) override
static css::uno::Reference< css::frame::XFrame > static_impl_searchRightTargetFrame(const css::uno::Reference< css::frame::XFrame > &xFrame, std::u16string_view sTarget)
try to find the right target frame where this close request must be really done.
EOperation m_eOperation
used inside asynchronous callback to decide, which operation must be executed.
bool implts_closeFrame()
close the member m_xCloseFrame.
css::uno::WeakReference< css::frame::XFrame > m_xCloseFrame
reference to the target frame, which should be closed by this dispatch.
virtual void SAL_CALL dispatch(const css::util::URL &aURL, const css::uno::Sequence< css::beans::PropertyValue > &lArguments) override
VclPtr< SystemWindow > m_pSysWindow
css::uno::Reference< css::frame::XDispatchResultListener > m_xResultListener
holded alive for internally asynchronous operations!
CloseDispatcher(css::uno::Reference< css::uno::XComponentContext > xContext, const css::uno::Reference< css::frame::XFrame > &xFrame, std::u16string_view sTarget)
connect a new CloseDispatcher instance to its frame.
bool implts_establishBackingMode()
set the special BackingComponent (now StartModule) as new component of our m_xCloseFrame.
URL aURL
float u
sal_Int32 nState
Reference< XInterface > xTarget
css::uno::Reference< css::uno::XComponentContext > m_xContext
bool closeIt(const css::uno::Reference< css::uno::XInterface > &xResource)
close (or dispose) the given resource.
Definition: frame.hxx:49
constexpr OUStringLiteral URL_CLOSEDOC
IMPL_LINK_NOARG(CloseDispatcher, impl_asyncCallback, LinkParamNone *, void)
asynchronous callback @descr We start all actions inside this object asynchronous (see comments there...
const char URL_CLOSEFRAME[]
constexpr OUStringLiteral URL_CLOSEWIN
int i
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
#define IMPLEMENTATIONNAME_QUICKLAUNCHER
Definition: services.h:37
Reference< XController > xController
Reference< XFrame > xFrame