tdf#126268: Add support for negative decimal
[LibreOffice.git] / sfx2 / inc / preventduplicateinteraction.hxx
blob1f96e8f94f084867d55c918018785849e72d06b2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #ifndef INCLUDED_FRAMEWORK_PREVENTDUPLICATEINTERACTION_HXX
21 #define INCLUDED_FRAMEWORK_PREVENTDUPLICATEINTERACTION_HXX
23 #include <vector>
25 #include <com/sun/star/frame/Desktop.hpp>
26 #include <com/sun/star/frame/TerminationVetoException.hpp>
27 #include <com/sun/star/frame/XTerminateListener2.hpp>
28 #include <com/sun/star/lang/XInitialization.hpp>
29 #include <com/sun/star/task/XInteractionHandler2.hpp>
30 #include <com/sun/star/task/XInteractionRequest.hpp>
32 #include <cppuhelper/compbase.hxx>
33 #include <cppuhelper/implbase.hxx>
35 #include <sfx2/app.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <vcl/wrkwin.hxx>
38 #include <vcl/svapp.hxx>
40 namespace com { namespace sun { namespace star { namespace uno {
41 class XComponentContext;
42 } } } }
44 namespace sfx2 {
46 inline void closedialogs(SystemWindow& rTopLevel, bool bCloseRoot)
48 for (vcl::Window *pChild = rTopLevel.GetWindow(GetWindowType::FirstTopWindowChild); pChild; pChild = rTopLevel.GetWindow(GetWindowType::NextTopWindowSibling))
49 closedialogs(dynamic_cast<SystemWindow&>(*pChild), true);
50 if (bCloseRoot)
51 rTopLevel.Close();
54 // This is intended to be the parent for any warning dialogs launched
55 // during the load of a document so that those dialogs are modal to
56 // this window and don't block any existing windows.
58 // If there are dialog children open on exit then veto termination,
59 // close the topmost dialog and retry termination.
60 class WarningDialogsParent :
61 public cppu::WeakComponentImplHelper<css::frame::XTerminateListener>
63 private:
64 osl::Mutex m_aLock;
65 VclPtr<WorkWindow> m_xWin;
66 css::uno::Reference<css::awt::XWindow> m_xInterface;
68 private:
70 DECL_STATIC_LINK(WarningDialogsParent, TerminateDesktop, void*, void);
72 void closewarningdialogs()
74 if (!m_xWin)
75 return;
76 SolarMutexGuard aSolarGuard;
77 closedialogs(dynamic_cast<SystemWindow&>(*m_xWin), false);
80 public:
82 using cppu::WeakComponentImplHelperBase::disposing;
83 virtual void SAL_CALL disposing(const css::lang::EventObject&) override
87 // XTerminateListener
88 virtual void SAL_CALL queryTermination(const css::lang::EventObject&) override
90 closewarningdialogs();
91 Application::PostUserEvent(LINK(this, WarningDialogsParent, TerminateDesktop));
92 throw css::frame::TerminationVetoException();
95 virtual void SAL_CALL notifyTermination(const css::lang::EventObject&) override
99 public:
100 WarningDialogsParent()
101 : cppu::WeakComponentImplHelper<css::frame::XTerminateListener>(m_aLock)
103 SolarMutexGuard aSolarGuard;
104 m_xWin = VclPtr<WorkWindow>::Create(nullptr, WB_STDWORK);
105 m_xWin->SetText("dialog parent for warning dialogs during load");
106 m_xInterface = VCLUnoHelper::GetInterface(m_xWin);
109 virtual ~WarningDialogsParent() override
111 closewarningdialogs();
112 m_xWin.disposeAndClear();
115 const css::uno::Reference<css::awt::XWindow>& GetDialogParent() const
117 return m_xInterface;
121 class WarningDialogsParentScope
123 private:
124 css::uno::Reference<css::frame::XDesktop> m_xDesktop;
125 rtl::Reference<WarningDialogsParent> m_xListener;
127 public:
128 WarningDialogsParentScope(const css::uno::Reference<css::uno::XComponentContext>& rContext)
129 : m_xDesktop(css::frame::Desktop::create(rContext), css::uno::UNO_QUERY_THROW)
130 , m_xListener(new WarningDialogsParent)
132 m_xDesktop->addTerminateListener(m_xListener.get());
135 const css::uno::Reference<css::awt::XWindow>& GetDialogParent() const
137 return m_xListener->GetDialogParent();
140 ~WarningDialogsParentScope()
142 m_xDesktop->removeTerminateListener(m_xListener.get());
147 @short Prevent us from showing the same interaction more than once during
148 the same transaction.
150 @descr Every interaction provided to this helper will be safed ... handled by the internal
151 used UUIInteractionHandler (!) and never be handled a second time!
153 On the other side there exists some interactions, which allow a retry.
154 So this helper allow to set a list of interactions combined with a retry value.
156 struct ThreadHelpBase2
158 public:
159 mutable ::osl::Mutex m_aLock;
162 class PreventDuplicateInteraction : private ThreadHelpBase2
163 , public ::cppu::WeakImplHelper<css::lang::XInitialization, css::task::XInteractionHandler2>
166 // structs, types etc.
167 public:
169 struct InteractionInfo
171 public:
172 /// describe the interaction.
173 css::uno::Type m_aInteraction;
174 /// after max count was reached this interaction will be blocked.
175 sal_Int32 m_nMaxCount;
176 /// count how often this interaction was called.
177 sal_Int32 m_nCallCount;
178 /** hold the last intercepted request (matching the set interaction type) alive
179 so it can be used for further checks */
180 css::uno::Reference< css::task::XInteractionRequest > m_xRequest;
182 public:
184 InteractionInfo(const css::uno::Type& aInteraction)
185 : m_aInteraction(aInteraction)
186 , m_nMaxCount (1 )
187 , m_nCallCount (0 )
191 typedef ::std::vector< InteractionInfo > InteractionList;
194 // member
195 private:
197 /// Used to create needed uno services at runtime.
198 css::uno::Reference< css::uno::XComponentContext > m_xContext;
200 /** The outside interaction handler, which is used to handle every incoming interaction,
201 if it's not blocked. */
202 css::uno::Reference< css::task::XInteractionHandler > m_xHandler;
204 std::unique_ptr<WarningDialogsParentScope> m_xWarningDialogsParent;
206 /** This list describe which and how incoming interactions must be handled.
207 Further it contains all collected information after this interaction
208 object was used.*/
209 InteractionList m_lInteractionRules;
212 // uno interface
213 public:
215 virtual void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override;
218 @interface XInteractionHandler
219 @short called from outside to handle a problem
220 @descr We filter the incoming interactions. some of them
221 will be forwarded to the generic UI interaction handler.
222 So we must not implement it twice. Some other ones
223 will be aborted only.
225 @threadsafe yes
227 virtual void SAL_CALL handle(const css::uno::Reference< css::task::XInteractionRequest >& xRequest) override;
231 @interface XInteractionHandler2
232 @short called from outside to handle a problem
233 @descr We filter the incoming interactions. some of them
234 will be forwarded to the generic UI interaction handler.
235 So we must not implement it twice. Some other ones
236 will be aborted only.
238 @threadsafe yes
240 virtual sal_Bool SAL_CALL handleInteractionRequest( const css::uno::Reference< css::task::XInteractionRequest >& xRequest ) override;
244 @interface XInterface
245 @short called to query another interface of the component
246 @descr Will allow to query for XInteractionHandler2 if and only if m_xHandler supports this interface, too.
248 @threadsafe yes
250 virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
252 // c++ interface
253 public:
257 @short ctor to guarantee right initialized instances of this class
258 @descr It uses the given uno service manager to create the global
259 generic UI interaction handler for later internal using.
261 @param xSMGR
262 uno service manager for creating services internally
264 @threadsafe not necessary
266 PreventDuplicateInteraction(const css::uno::Reference< css::uno::XComponentContext >& rxContext);
270 @short dtor to free used memory.
272 virtual ~PreventDuplicateInteraction() override;
276 @short set the outside interaction handler, which must be used internally
277 if the interaction will not be blocked by the set list of rules.
279 @note This overwrites the settings of e.g. useDefaultUUIHandler()!
281 @param xHandler
282 the new interaction handler
284 void setHandler(const css::uno::Reference< css::task::XInteractionHandler >& xHandler);
288 @short instead of setting an outside interaction handler, this method
289 make sure the default UUI interaction handler of the office is used.
291 @note This overwrites the settings of e.g. setHandler()!
293 void useDefaultUUIHandler();
297 @short add a new interaction to the list of interactions, which
298 must be handled by this helper.
300 @descr This method must be called immediately after a new instance of this helper was
301 created. Without such list of InteractionRules, this instances does nothing!
302 On the other side there is no possibility to remove rules.
303 So the same instance can't be used within different transactions.
304 It's a OneWay-object .-)
306 @param aInteractionInfo
307 describe the type of interaction, hos often it can be called etcpp.
309 @threadsafe yes
311 void addInteractionRule(const PreventDuplicateInteraction::InteractionInfo& aInteractionInfo);
315 @short return the info struct for the specified interaction.
317 @param aInteraction
318 specify the interaction.
320 @param pReturn
321 provides information about:
322 - the count how often this interaction was handled during the
323 lifetime of this helper.
324 - the interaction itself, so it can be analyzed further
326 @return [boolean]
327 true if the queried interaction could be found.
328 false otherwise.
330 @threadsafe yes
332 bool getInteractionInfo(const css::uno::Type& aInteraction,
333 PreventDuplicateInteraction::InteractionInfo* pReturn ) const;
336 } // namespace sfx2
338 #endif // INCLUDED_FRAMEWORK_PREVENTDUPLICATEINTERACTION_HXX
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */