Avoid potential negative array index access to cached text.
[LibreOffice.git] / extensions / source / propctrlr / composeduiupdate.hxx
blob5e356af1f9093eb9581c4262330fa3804ad63ad7
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 #pragma once
22 #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
23 #include <com/sun/star/inspection/XPropertyHandler.hpp>
25 #include <memory>
28 namespace pcr
31 struct MapHandlerToUI;
33 /** callback for a ComposedPropertyUIUpdate checking a given property for existence
35 class SAL_NO_VTABLE IPropertyExistenceCheck
37 public:
38 /// @throws css::uno::RuntimeException
39 virtual bool hasPropertyByName( const OUString& _rName ) = 0;
41 protected:
42 ~IPropertyExistenceCheck() {}
45 /** helper class composing requests to a ->XObjectInspectorUI interface, coming
46 from multiple sources
48 Usually, a handler tells the browser UI to enable to disable, or show or hide, certain
49 elements. Now when multiple handlers do this, their instructions must be combined:
50 If one handler disables a certain element, but others enable it, it must in the
51 result still be disabled. Similar for showing/hiding elements.
53 ->ComposedPropertyUIUpdate implements this combination. It does so by providing a dedicated
54 ->XObjectInspectorUI instance for every participating handler, and remembering the UI
55 state on a per-handler basis. Upon request (->fire), the combined UI state is
56 forwarded to another ->XObjectInspectorUI instance, the so-called delegator UI.
58 class ComposedPropertyUIUpdate
60 private:
61 std::unique_ptr< MapHandlerToUI > m_pCollectedUIs;
62 css::uno::Reference< css::inspection::XObjectInspectorUI >
63 m_xDelegatorUI;
64 oslInterlockedCount m_nSuspendCounter;
65 IPropertyExistenceCheck* m_pPropertyCheck;
67 public:
68 /** constructs a ->ComposedPropertyUIUpdate instance
69 @param _rxDelegatorUI
70 a ->XObjectInspectorUI instance to which composed UI requests should be forwarded. Must
71 not be <NULL/>.
72 @param _pPropertyCheck
73 an instance checking properties for existence. If this is not <NULL/>, it will be invoked
74 whenever one of the ->XObjectInspectorUI methods is called, to check the passed property
75 name.<br/>
76 Beware of lifetime issues. The instance pointed to by <arg>_pPropertyCheck</arg> must
77 live at least as long as the ->ComposedPropertyUIUpdate instance you're going to create.
78 @throws css::lang::NullPointerException
79 if ->_rxDelegatorUI is <NULL/>
81 ComposedPropertyUIUpdate(
82 const css::uno::Reference< css::inspection::XObjectInspectorUI >& _rxDelegatorUI,
83 IPropertyExistenceCheck* _pPropertyCheck );
84 ~ComposedPropertyUIUpdate();
86 /** returns the delegator UI
87 @throw css::lang::DisposedException
89 css::uno::Reference< css::inspection::XObjectInspectorUI > const & getDelegatorUI() const;
91 /** returns a ->XObjectInspectorUI instance belonging to a given property handler
93 In every call to an ->XPropertyHandler method which requires a ->XObjectInspectorUI,
94 the same UI instance should be used. The instance here will cache all requests passed
95 to it, and ->ComposedPropertyUIUpdate::fire will use the combination of all
96 cached UI states of all handlers to update the delegator UI.
98 css::uno::Reference< css::inspection::XObjectInspectorUI >
99 getUIForPropertyHandler( const css::uno::Reference< css::inspection::XPropertyHandler >& _rxHandler );
101 /** Suspends automatic firing of UI changes
103 normally, as soon as any of the property handlers does a request for an
104 arbitrary UI change, the set of collected UI changes is evaluated, and the combined
105 UI state is fired to the delegator UI.
107 You can disable this automatic firing by calling ->suspendAutoFire. As longs as auto
108 firing is suspended, only explicit ->fire calls trigger the notification to the
109 delegator UI.
111 Note that calls to ->suspendAutoFire are cumulative, that is, if you make multiple calls
112 they must be accompanied by an equal number of calls to ->resumeAutoFire, to enable
113 auto-firing again.
115 @seealso resumeAutoFire
117 void suspendAutoFire();
119 /** Suspends automatic firing of UI changes
121 @seealso suspendAutoFire
123 void resumeAutoFire();
125 /** disposes the instance, so it becomes non-functional.
127 All cached handlers and cached ->XObjectInspectorUI instances will be released,
128 the latter will also be disposed, so that if anybody still holds a reference to them
129 and tries to operate them will get a DisposedException.
131 void dispose();
133 /** invokes m_pPropertyCheck to check whether a given property should be handled
135 bool shouldContinuePropertyHandling( const OUString& _rName ) const;
137 private:
138 /// determines whether the instance is already disposed
139 bool impl_isDisposed() const { return !m_pCollectedUIs; }
141 /// throws an exception if the component is already disposed
142 void impl_checkDisposed() const;
144 /** fires the collected UI changes to our delegator UI
146 All operations for any elements are forwarded:
147 <ul><li>If an element has been hidden at least once, it's also hidden at the delegator UI.</li>
148 <li>If an element has been shown at least once, and never been hidden, it's also
149 shown at the delegator UI.</li>
150 <li>If an element has never been shown or hidden, it's also not touched at the delegator UI.</li>
151 <li>The same holds if you replace "hidden" in the last three items with "disabled",
152 and "shown" with "enabled".</li>
153 <li>If an element should have been rebuilt (->XObjectInspectorUI::rebuiltPropertyUI)
154 at least once, it's rebuilt at the delegator UI, too.<br/>
155 After that, the request to rebuild the UI for this property is cleared, so subsequent
156 calls to ->fire will not trigger a new rebuilt request.
157 </ul>
159 @precond
160 instance is not disposed
162 void impl_fireAll_throw();
164 /// fires the combination of ->XObjectInspectorUI::enablePropertyUI calls
165 void impl_fireEnablePropertyUI_throw();
167 /// fires the combination of ->XObjectInspectorUI::enablePropertyUIElements calls
168 void impl_fireEnablePropertyUIElements_throw();
170 /// fires the combination of ->XObjectInspectorUI::rebuildPropertyUI calls
171 void impl_fireRebuildPropertyUI_throw();
173 /// fires the combination of ->XObjectInspectorUI::showPropertyUI and ->XObjectInspectorUI::hidePropertyUI calls
174 void impl_fireShowHidePropertyUI_throw();
176 /// fires the combination of ->XObjectInspectorUI::showCategory calls
177 void impl_fireShowCategory_throw();
179 /** callback for when a single property handler requested any change in the inspector UI
181 void callback_inspectorUIChanged_throw();
183 private:
184 ComposedPropertyUIUpdate( const ComposedPropertyUIUpdate& ) = delete;
185 ComposedPropertyUIUpdate& operator=( const ComposedPropertyUIUpdate& ) = delete;
188 class ComposedUIAutoFireGuard
190 private:
191 ComposedPropertyUIUpdate& m_rUIUpdate;
192 public:
193 explicit ComposedUIAutoFireGuard( ComposedPropertyUIUpdate& _rUIUpdate )
194 :m_rUIUpdate( _rUIUpdate )
196 m_rUIUpdate.suspendAutoFire();
198 ~ComposedUIAutoFireGuard() COVERITY_NOEXCEPT_FALSE
200 m_rUIUpdate.resumeAutoFire();
205 } // namespace pcr
208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */