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
)
32 , m_xContext(rxContext
)
36 PreventDuplicateInteraction::~PreventDuplicateInteraction()
40 void PreventDuplicateInteraction::setHandler(const css::uno::Reference
< css::task::XInteractionHandler
>& xHandler
)
43 osl::MutexGuard
aLock(m_aLock
);
44 m_xWarningDialogsParent
.reset();
45 m_xHandler
= xHandler
;
49 void PreventDuplicateInteraction::useDefaultUUIHandler()
51 //if we use the default handler, set the parent to a window belonging to this object so that the dialogs
52 //don't block unrelated windows.
53 m_xWarningDialogsParent
.reset(new WarningDialogsParentScope(m_xContext
));
54 css::uno::Reference
<css::task::XInteractionHandler
> xHandler(css::task::InteractionHandler::createWithParent(
55 m_xContext
, m_xWarningDialogsParent
->GetDialogParent()), css::uno::UNO_QUERY_THROW
);
58 osl::MutexGuard
aLock(m_aLock
);
59 m_xHandler
= xHandler
;
63 css::uno::Any SAL_CALL
PreventDuplicateInteraction::queryInterface( const css::uno::Type
& aType
)
65 if ( aType
.equals( cppu::UnoType
<XInteractionHandler2
>::get() ) )
67 osl::MutexGuard
aLock(m_aLock
);
68 css::uno::Reference
< css::task::XInteractionHandler2
> xHandler( m_xHandler
, css::uno::UNO_QUERY
);
70 return css::uno::Any();
72 return ::cppu::WeakImplHelper
<css::lang::XInitialization
, css::task::XInteractionHandler2
>::queryInterface(aType
);
75 void SAL_CALL
PreventDuplicateInteraction::handle(const css::uno::Reference
< css::task::XInteractionRequest
>& xRequest
)
77 css::uno::Any aRequest
= xRequest
->getRequest();
78 bool bHandleIt
= true;
81 osl::ClearableMutexGuard
aLock(m_aLock
);
83 auto pIt
= std::find_if(m_lInteractionRules
.begin(), m_lInteractionRules
.end(),
84 [&aRequest
](const InteractionInfo
& rInfo
) { return aRequest
.isExtractableTo(rInfo
.m_aInteraction
); });
85 if (pIt
!= m_lInteractionRules
.end())
87 InteractionInfo
& rInfo
= *pIt
;
90 rInfo
.m_xRequest
= xRequest
;
91 bHandleIt
= (rInfo
.m_nCallCount
<= rInfo
.m_nMaxCount
);
94 css::uno::Reference
< css::task::XInteractionHandler
> xHandler
= m_xHandler
;
99 if ( bHandleIt
&& xHandler
.is() )
101 xHandler
->handle(xRequest
);
105 const css::uno::Sequence
< css::uno::Reference
< css::task::XInteractionContinuation
> > lContinuations
= xRequest
->getContinuations();
106 for (const auto& rContinuation
: lContinuations
)
108 css::uno::Reference
< css::task::XInteractionAbort
> xAbort(rContinuation
, css::uno::UNO_QUERY
);
118 sal_Bool SAL_CALL
PreventDuplicateInteraction::handleInteractionRequest( const css::uno::Reference
< css::task::XInteractionRequest
>& xRequest
)
120 css::uno::Any aRequest
= xRequest
->getRequest();
121 bool bHandleIt
= true;
124 osl::ClearableMutexGuard
aLock(m_aLock
);
126 auto pIt
= std::find_if(m_lInteractionRules
.begin(), m_lInteractionRules
.end(),
127 [&aRequest
](const InteractionInfo
& rInfo
) { return aRequest
.isExtractableTo(rInfo
.m_aInteraction
); });
128 if (pIt
!= m_lInteractionRules
.end())
130 InteractionInfo
& rInfo
= *pIt
;
132 ++rInfo
.m_nCallCount
;
133 rInfo
.m_xRequest
= xRequest
;
134 bHandleIt
= (rInfo
.m_nCallCount
<= rInfo
.m_nMaxCount
);
137 css::uno::Reference
< css::task::XInteractionHandler2
> xHandler( m_xHandler
, css::uno::UNO_QUERY
);
138 OSL_ENSURE( xHandler
.is() || !m_xHandler
.is(),
139 "PreventDuplicateInteraction::handleInteractionRequest: inconsistency!" );
144 if ( bHandleIt
&& xHandler
.is() )
146 return xHandler
->handleInteractionRequest(xRequest
);
150 const css::uno::Sequence
< css::uno::Reference
< css::task::XInteractionContinuation
> > lContinuations
= xRequest
->getContinuations();
151 for (const auto& rContinuation
: lContinuations
)
153 css::uno::Reference
< css::task::XInteractionAbort
> xAbort(rContinuation
, css::uno::UNO_QUERY
);
164 void PreventDuplicateInteraction::addInteractionRule(const PreventDuplicateInteraction::InteractionInfo
& aInteractionInfo
)
167 osl::MutexGuard
aLock(m_aLock
);
169 auto pIt
= std::find_if(m_lInteractionRules
.begin(), m_lInteractionRules
.end(),
170 [&aInteractionInfo
](const InteractionInfo
& rInfo
) { return rInfo
.m_aInteraction
== aInteractionInfo
.m_aInteraction
; });
171 if (pIt
!= m_lInteractionRules
.end())
173 InteractionInfo
& rInfo
= *pIt
;
174 rInfo
.m_nMaxCount
= aInteractionInfo
.m_nMaxCount
;
175 rInfo
.m_nCallCount
= aInteractionInfo
.m_nCallCount
;
179 m_lInteractionRules
.push_back(aInteractionInfo
);
183 bool PreventDuplicateInteraction::getInteractionInfo(const css::uno::Type
& aInteraction
,
184 PreventDuplicateInteraction::InteractionInfo
* pReturn
) const
187 osl::MutexGuard
aLock(m_aLock
);
189 auto pIt
= std::find_if(m_lInteractionRules
.begin(), m_lInteractionRules
.end(),
190 [&aInteraction
](const InteractionInfo
& rInfo
) { return rInfo
.m_aInteraction
== aInteraction
; });
191 if (pIt
!= m_lInteractionRules
.end())
201 void SAL_CALL
PreventDuplicateInteraction::initialize(const css::uno::Sequence
<css::uno::Any
>& rArguments
)
203 // If we're re-initialized to set a specific new window as a parent then drop our temporary
205 css::uno::Reference
<css::lang::XInitialization
> xHandler(m_xHandler
, css::uno::UNO_QUERY
);
208 m_xWarningDialogsParent
.reset();
209 xHandler
->initialize(rArguments
);
213 IMPL_STATIC_LINK_NOARG(WarningDialogsParent
, TerminateDesktop
, void*, void)
215 css::frame::Desktop::create(comphelper::getProcessComponentContext())->terminate();
220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */