1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <preventduplicateinteraction.hxx>
22 #include <comphelper/processfactory.hxx>
23 #include <osl/diagnose.h>
25 #include <com/sun/star/task/InteractionHandler.hpp>
26 #include <com/sun/star/task/XInteractionAbort.hpp>
30 PreventDuplicateInteraction::PreventDuplicateInteraction(const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
)
31 : m_xContext(rxContext
)
35 PreventDuplicateInteraction::~PreventDuplicateInteraction()
39 void PreventDuplicateInteraction::setHandler(const css::uno::Reference
< css::task::XInteractionHandler
>& xHandler
)
42 osl::MutexGuard
aLock(m_aLock
);
43 m_xWarningDialogsParent
.reset();
44 m_xHandler
= xHandler
;
48 void PreventDuplicateInteraction::useDefaultUUIHandler()
50 //if we use the default handler, set the parent to a window belonging to this object so that the dialogs
51 //don't block unrelated windows.
52 m_xWarningDialogsParent
.reset(new WarningDialogsParentScope(m_xContext
));
53 css::uno::Reference
<css::task::XInteractionHandler
> xHandler(css::task::InteractionHandler::createWithParent(
54 m_xContext
, m_xWarningDialogsParent
->GetDialogParent()), css::uno::UNO_QUERY_THROW
);
57 osl::MutexGuard
aLock(m_aLock
);
58 m_xHandler
= xHandler
;
62 css::uno::Any SAL_CALL
PreventDuplicateInteraction::queryInterface( const css::uno::Type
& aType
)
64 if ( aType
.equals( cppu::UnoType
<XInteractionHandler2
>::get() ) )
66 osl::MutexGuard
aLock(m_aLock
);
67 css::uno::Reference
< css::task::XInteractionHandler2
> xHandler( m_xHandler
, css::uno::UNO_QUERY
);
69 return css::uno::Any();
71 return ::cppu::WeakImplHelper
<css::lang::XInitialization
, css::task::XInteractionHandler2
>::queryInterface(aType
);
74 void SAL_CALL
PreventDuplicateInteraction::handle(const css::uno::Reference
< css::task::XInteractionRequest
>& xRequest
)
76 css::uno::Any aRequest
= xRequest
->getRequest();
77 bool bHandleIt
= true;
80 osl::ClearableMutexGuard
aLock(m_aLock
);
82 auto pIt
= std::find_if(m_lInteractionRules
.begin(), m_lInteractionRules
.end(),
83 [&aRequest
](const InteractionInfo
& rInfo
) { return aRequest
.isExtractableTo(rInfo
.m_aInteraction
); });
84 if (pIt
!= m_lInteractionRules
.end())
86 InteractionInfo
& rInfo
= *pIt
;
89 rInfo
.m_xRequest
= xRequest
;
90 bHandleIt
= (rInfo
.m_nCallCount
<= rInfo
.m_nMaxCount
);
93 css::uno::Reference
< css::task::XInteractionHandler
> xHandler
= m_xHandler
;
98 if ( bHandleIt
&& xHandler
.is() )
100 xHandler
->handle(xRequest
);
104 const css::uno::Sequence
< css::uno::Reference
< css::task::XInteractionContinuation
> > lContinuations
= xRequest
->getContinuations();
105 for (const auto& rContinuation
: lContinuations
)
107 css::uno::Reference
< css::task::XInteractionAbort
> xAbort(rContinuation
, css::uno::UNO_QUERY
);
117 sal_Bool SAL_CALL
PreventDuplicateInteraction::handleInteractionRequest( const css::uno::Reference
< css::task::XInteractionRequest
>& xRequest
)
119 css::uno::Any aRequest
= xRequest
->getRequest();
120 bool bHandleIt
= true;
123 osl::ClearableMutexGuard
aLock(m_aLock
);
125 auto pIt
= std::find_if(m_lInteractionRules
.begin(), m_lInteractionRules
.end(),
126 [&aRequest
](const InteractionInfo
& rInfo
) { return aRequest
.isExtractableTo(rInfo
.m_aInteraction
); });
127 if (pIt
!= m_lInteractionRules
.end())
129 InteractionInfo
& rInfo
= *pIt
;
131 ++rInfo
.m_nCallCount
;
132 rInfo
.m_xRequest
= xRequest
;
133 bHandleIt
= (rInfo
.m_nCallCount
<= rInfo
.m_nMaxCount
);
136 css::uno::Reference
< css::task::XInteractionHandler2
> xHandler( m_xHandler
, css::uno::UNO_QUERY
);
137 OSL_ENSURE( xHandler
.is() || !m_xHandler
.is(),
138 "PreventDuplicateInteraction::handleInteractionRequest: inconsistency!" );
143 if ( bHandleIt
&& xHandler
.is() )
145 return xHandler
->handleInteractionRequest(xRequest
);
149 const css::uno::Sequence
< css::uno::Reference
< css::task::XInteractionContinuation
> > lContinuations
= xRequest
->getContinuations();
150 for (const auto& rContinuation
: lContinuations
)
152 css::uno::Reference
< css::task::XInteractionAbort
> xAbort(rContinuation
, css::uno::UNO_QUERY
);
163 void PreventDuplicateInteraction::addInteractionRule(const PreventDuplicateInteraction::InteractionInfo
& aInteractionInfo
)
166 osl::MutexGuard
aLock(m_aLock
);
168 auto pIt
= std::find_if(m_lInteractionRules
.begin(), m_lInteractionRules
.end(),
169 [&aInteractionInfo
](const InteractionInfo
& rInfo
) { return rInfo
.m_aInteraction
== aInteractionInfo
.m_aInteraction
; });
170 if (pIt
!= m_lInteractionRules
.end())
172 InteractionInfo
& rInfo
= *pIt
;
173 rInfo
.m_nMaxCount
= aInteractionInfo
.m_nMaxCount
;
174 rInfo
.m_nCallCount
= aInteractionInfo
.m_nCallCount
;
178 m_lInteractionRules
.push_back(aInteractionInfo
);
182 bool PreventDuplicateInteraction::getInteractionInfo(const css::uno::Type
& aInteraction
,
183 PreventDuplicateInteraction::InteractionInfo
* pReturn
) const
186 osl::MutexGuard
aLock(m_aLock
);
188 auto pIt
= std::find_if(m_lInteractionRules
.begin(), m_lInteractionRules
.end(),
189 [&aInteraction
](const InteractionInfo
& rInfo
) { return rInfo
.m_aInteraction
== aInteraction
; });
190 if (pIt
!= m_lInteractionRules
.end())
200 void SAL_CALL
PreventDuplicateInteraction::initialize(const css::uno::Sequence
<css::uno::Any
>& rArguments
)
202 // If we're re-initialized to set a specific new window as a parent then drop our temporary
204 css::uno::Reference
<css::lang::XInitialization
> xHandler(m_xHandler
, css::uno::UNO_QUERY
);
207 m_xWarningDialogsParent
.reset();
208 xHandler
->initialize(rArguments
);
212 IMPL_STATIC_LINK_NOARG(WarningDialogsParent
, TerminateDesktop
, void*, void)
214 css::frame::Desktop::create(comphelper::getProcessComponentContext())->terminate();
219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */