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>
38#include <osl/diagnose.h>
51 #error "Who uses \"fpf\" as define. It will overwrite my namespace alias ..."
53namespace fpf = ::framework::pattern::frame;
60 const css::uno::Reference< css::frame::XFrame >& xFrame ,
61 std::u16string_view sTarget)
65 , m_eOperation(E_CLOSE_DOC)
66 , m_pSysWindow(nullptr)
72 uno::Reference<awt::XWindow> xWindow =
xTarget->getContainerWindow();
76 if (pWindow->IsSystemWindow())
89 const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
96 return css::uno::Sequence< sal_Int16 >{css::frame::CommandGroup::VIEW, css::frame::CommandGroup::DOCUMENT};
101 if (nCommandGroup == css::frame::CommandGroup::VIEW)
106 css::uno::Sequence< css::frame::DispatchInformation > lViewInfos{
111 else if (nCommandGroup == css::frame::CommandGroup::DOCUMENT)
113 css::uno::Sequence< css::frame::DispatchInformation > lDocInfos{
119 return css::uno::Sequence< css::frame::DispatchInformation >();
123 const css::util::URL& )
128 const css::util::URL& )
133 const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
134 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
152 css::frame::DispatchResultState::DONTKNOW,
174 css::frame::DispatchResultState::FAILURE,
189 css::frame::DispatchResultState::SUCCESS,
211 bool bIsSynchron =
false;
212 for (
const css::beans::PropertyValue& rArg : lArguments )
214 if ( rArg.Name ==
"SynchronMode" )
216 rArg.Value >>= bIsSynchron;
222 impl_asyncCallback(
nullptr);
254 bool bControllerSuspended =
false;
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;
266 bCloseAllViewsToo = (m_eOperation == E_CLOSE_DOC);
268 eOperation = m_eOperation;
270 xCloseFrame.set(m_xCloseFrame.get(), css::uno::UNO_QUERY);
271 xListener = m_xResultListener;
276 if (! xCloseFrame.is())
279 bool bCloseFrame =
false;
280 bool bEstablishBackingMode =
false;
281 bool bTerminateApp =
false;
286 css::uno::Reference< css::frame::XFramesSupplier > xDesktop( css::frame::Desktop::create(xContext), css::uno::UNO_QUERY_THROW);
292 css::uno::Reference<css::bridge::XBridgeFactory2> bridgeFac( css::bridge::BridgeFactory::create(xContext) );
293 bool bHasActiveConnections = bridgeFac->getExistingBridges().hasElements();
301 if ( ! xCloseFrame->getCreator().is())
309 else if (aCheck1.m_bReferenceIsHelp)
315 else if (aCheck1.m_bReferenceIsBacking) {
316 if (bHasActiveConnections)
319 bTerminateApp =
true;
326 if (implts_prepareFrameForClosing(m_xCloseFrame, bCloseAllViewsToo, bControllerSuspended))
338 if (!aCheck2.m_lOtherVisibleFrames.empty() || (!aCheck2.m_bReferenceIsBacking && aCheck2.m_xBackingComponent.is()))
347 (!bCloseAllViewsToo ) &&
348 (!aCheck2.m_lModelFrames.empty())
359 if (eOperation == E_CLOSE_FRAME)
361 if (bHasActiveConnections)
364 bTerminateApp =
true;
367 bEstablishBackingMode =
true;
368 else if (bHasActiveConnections)
371 bTerminateApp =
true;
377 bool bSuccess =
false;
379 bSuccess = implts_closeFrame();
380 else if (bEstablishBackingMode)
387 bool bQuickstarterRunning =
false;
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 ) );
394 if( aVal >>= bState )
395 bQuickstarterRunning = bState;
397 catch(
const css::uno::Exception& )
400 bSuccess = bQuickstarterRunning ? implts_terminateApplication() : implts_establishBackingMode();
403 bSuccess = implts_establishBackingMode();
405 else if (bTerminateApp)
406 bSuccess = implts_terminateApplication();
408 if ( ! bSuccess && bControllerSuspended )
410 css::uno::Reference< css::frame::XController >
xController = xCloseFrame->getController();
416 sal_Int16
nState = css::frame::DispatchResultState::FAILURE;
418 nState = css::frame::DispatchResultState::SUCCESS;
419 implts_notifyResultListener(xListener,
nState, css::uno::Any());
427 css::uno::Reference< css::uno::XInterface > xTempHold = m_xSelfHold;
429 m_xResultListener.clear();
431 catch(
const css::lang::DisposedException&)
437 bool bCloseAllOtherViewsToo,
438 bool& bControllerSuspended )
448 if (bCloseAllOtherViewsToo)
450 css::uno::Reference< css::uno::XComponentContext > xContext;
456 css::uno::Reference< css::frame::XFramesSupplier > xDesktop( css::frame::Desktop::create( xContext ), css::uno::UNO_QUERY_THROW);
459 size_t c = aCheck.m_lModelFrames.size();
470 css::uno::Reference< css::frame::XController >
xController =
xFrame->getController();
474 if (! bControllerSuspended)
487 css::uno::Reference< css::frame::XFrame >
xFrame;
513 css::uno::Reference< css::uno::XComponentContext > xContext;
514 css::uno::Reference< css::frame::XFrame >
xFrame;
524 css::uno::Reference < css::document::XActionLockable > xLock(
xFrame, css::uno::UNO_QUERY );
525 if ( xLock.is() && xLock->isActionLocked() )
528 css::uno::Reference< css::awt::XWindow > xContainerWindow =
xFrame->getContainerWindow();
530 css::uno::Reference< css::frame::XController > xStartModule = css::frame::StartModule::createWithParentWindow(
531 xContext, xContainerWindow);
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);
544 css::uno::Reference< css::uno::XComponentContext > xContext;
550 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext );
552 return xDesktop->terminate();
557 const css::uno::Any& aResult )
562 css::frame::DispatchResultEvent
aEvent(
563 css::uno::Reference< css::uno::XInterface >(
static_cast< ::
cppu::OWeakObject*
>(
this), css::uno::UNO_QUERY),
567 xListener->dispatchFinished(
aEvent);
571 std::u16string_view sTarget)
576 OSL_ENSURE(sTarget.empty(),
"CloseDispatch used for unexpected target. Magic things will happen now .-)");
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())
597 if ( pWindow && pWindow->IsSystemWindow() )
604 css::uno::Reference< css::frame::XFrame > xParent =
xTarget->getCreator();
vcl::EventPoster m_aAsyncCallback
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.
Reference< XInterface > xTarget
css::uno::Reference< css::uno::XComponentContext > m_xContext
#define LINK(Instance, Class, Member)
bool closeIt(const css::uno::Reference< css::uno::XInterface > &xResource)
close (or dispose) the given resource.
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
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
#define IMPLEMENTATIONNAME_QUICKLAUNCHER
Reference< XController > xController
Reference< XFrame > xFrame