1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski #ifndef EXTENSIONS_SOURCE_PROPCTRLR_COMPOSEDUIUPDATE_HXX
25*b1cdbd2cSJim Jagielski #define EXTENSIONS_SOURCE_PROPCTRLR_COMPOSEDUIUPDATE_HXX
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include "propertyhandler.hxx"
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski /** === begin UNO includes === **/
30*b1cdbd2cSJim Jagielski #include <com/sun/star/inspection/XObjectInspectorUI.hpp>
31*b1cdbd2cSJim Jagielski /** === end UNO includes === **/
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski #include <map>
34*b1cdbd2cSJim Jagielski #include <set>
35*b1cdbd2cSJim Jagielski #include <memory>
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski //........................................................................
38*b1cdbd2cSJim Jagielski namespace pcr
39*b1cdbd2cSJim Jagielski {
40*b1cdbd2cSJim Jagielski //........................................................................
41*b1cdbd2cSJim Jagielski 
42*b1cdbd2cSJim Jagielski     //====================================================================
43*b1cdbd2cSJim Jagielski 	//= some helper types
44*b1cdbd2cSJim Jagielski 	//====================================================================
45*b1cdbd2cSJim Jagielski 
46*b1cdbd2cSJim Jagielski     struct MapHandlerToUI;
47*b1cdbd2cSJim Jagielski 
48*b1cdbd2cSJim Jagielski     /** callback for an ComposedPropertyUIUpdate checking a given property for existence
49*b1cdbd2cSJim Jagielski     */
50*b1cdbd2cSJim Jagielski     class SAL_NO_VTABLE IPropertyExistenceCheck
51*b1cdbd2cSJim Jagielski     {
52*b1cdbd2cSJim Jagielski     public:
53*b1cdbd2cSJim Jagielski         virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& _rName ) throw (::com::sun::star::uno::RuntimeException) = 0;
54*b1cdbd2cSJim Jagielski     };
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski     //====================================================================
57*b1cdbd2cSJim Jagielski 	//= ComposedPropertyUIUpdate
58*b1cdbd2cSJim Jagielski 	//====================================================================
59*b1cdbd2cSJim Jagielski     /** helper class composing requests to a ->XObjectInspectorUI interface, coming
60*b1cdbd2cSJim Jagielski         from multiple sources
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski         Usually, a handler tells the browser UI to enable to disable, or show or hide, certain
63*b1cdbd2cSJim Jagielski         elements. Now when multiple handlers do this, their instructions must be combined:
64*b1cdbd2cSJim Jagielski         If one handler disables a certain element, but others enable it, it must in the
65*b1cdbd2cSJim Jagielski         result still be disabled. Similar for showing/hiding elements.
66*b1cdbd2cSJim Jagielski 
67*b1cdbd2cSJim Jagielski         ->ComposedPropertyUIUpdate implements this combination. It does so by providing a dedicated
68*b1cdbd2cSJim Jagielski         ->XObjectInspectorUI instance for every participating handler, and remembering the UI
69*b1cdbd2cSJim Jagielski         state on a per-handler basis. Upon request (->fire), the combined UI state is
70*b1cdbd2cSJim Jagielski         forwarded to another ->XObjectInspectorUI instance, the so-called delegator UI.
71*b1cdbd2cSJim Jagielski     */
72*b1cdbd2cSJim Jagielski     class ComposedPropertyUIUpdate
73*b1cdbd2cSJim Jagielski     {
74*b1cdbd2cSJim Jagielski     private:
75*b1cdbd2cSJim Jagielski         ::std::auto_ptr< MapHandlerToUI >       m_pCollectedUIs;
76*b1cdbd2cSJim Jagielski         ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >
77*b1cdbd2cSJim Jagielski                                                 m_xDelegatorUI;
78*b1cdbd2cSJim Jagielski         oslInterlockedCount                     m_nSuspendCounter;
79*b1cdbd2cSJim Jagielski         IPropertyExistenceCheck*                m_pPropertyCheck;
80*b1cdbd2cSJim Jagielski 
81*b1cdbd2cSJim Jagielski     public:
82*b1cdbd2cSJim Jagielski         /** constructs a ->ComposedPropertyUIUpdate instance
83*b1cdbd2cSJim Jagielski             @param _rxDelegatorUI
84*b1cdbd2cSJim Jagielski                 a ->XObjectInspectorUI instance to which composed UI requests should be forwarded. Must
85*b1cdbd2cSJim Jagielski                 not be <NULL/>.
86*b1cdbd2cSJim Jagielski             @param _pPropertyCheck
87*b1cdbd2cSJim Jagielski                 an instance checking properties for existence. If this is not <NULL/>, it will be invoked
88*b1cdbd2cSJim Jagielski                 whenever one of the ->XObjectInspectorUI methods is called, to check the passed property
89*b1cdbd2cSJim Jagielski                 name.<br/>
90*b1cdbd2cSJim Jagielski                 Beware of lifetime issues. The instance pointed to by <arg>_pPropertyCheck</arg> must
91*b1cdbd2cSJim Jagielski                 live at least as long as the ->ComposedPropertyUIUpdate instance you're going to create.
92*b1cdbd2cSJim Jagielski             @throws ::com::sun::star::lang::NullPointerException
93*b1cdbd2cSJim Jagielski                 if ->_rxDelegatorUI is <NULL/>
94*b1cdbd2cSJim Jagielski         */
95*b1cdbd2cSJim Jagielski         ComposedPropertyUIUpdate(
96*b1cdbd2cSJim Jagielski             const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >& _rxDelegatorUI,
97*b1cdbd2cSJim Jagielski             IPropertyExistenceCheck* _pPropertyCheck );
98*b1cdbd2cSJim Jagielski         ~ComposedPropertyUIUpdate();
99*b1cdbd2cSJim Jagielski 
100*b1cdbd2cSJim Jagielski         /** returns the delegator UI
101*b1cdbd2cSJim Jagielski             @throw ::com::sun::star::lang::DisposedException
102*b1cdbd2cSJim Jagielski         */
103*b1cdbd2cSJim Jagielski         ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI > getDelegatorUI() const;
104*b1cdbd2cSJim Jagielski 
105*b1cdbd2cSJim Jagielski         /** returns a ->XObjectInspectorUI instance belonging to a given property handler
106*b1cdbd2cSJim Jagielski 
107*b1cdbd2cSJim Jagielski             In every call to an ->XPropertyHandler method which requires a ->XObjectInspectorUI,
108*b1cdbd2cSJim Jagielski             the same UI instance should be used. The instance here will cache all requests passed
109*b1cdbd2cSJim Jagielski             to it, and ->ComposedPropertyUIUpdate::fire will use the combination of all
110*b1cdbd2cSJim Jagielski             cached UI states of all handlers to update the delegator UI.
111*b1cdbd2cSJim Jagielski         */
112*b1cdbd2cSJim Jagielski         ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XObjectInspectorUI >
113*b1cdbd2cSJim Jagielski             getUIForPropertyHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyHandler >& _rxHandler );
114*b1cdbd2cSJim Jagielski 
115*b1cdbd2cSJim Jagielski         /** Suspends automatic firing of UI changes
116*b1cdbd2cSJim Jagielski 
117*b1cdbd2cSJim Jagielski             normally, as soon as any of the property handlers does a request for an
118*b1cdbd2cSJim Jagielski             arbitrary UI change, the set of collected UI changes is evaluated, and the combined
119*b1cdbd2cSJim Jagielski             UI state is fired to the delegator UI.
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski             You can disable this automatic firing by calling ->suspendAutoFire. As longs as auto
122*b1cdbd2cSJim Jagielski             firing is suspended, only explicit ->fire calls trigger the notification to the
123*b1cdbd2cSJim Jagielski             delegator UI.
124*b1cdbd2cSJim Jagielski 
125*b1cdbd2cSJim Jagielski             Note that calls to ->suspendAutoFire are culmulative, that is, if you make multiple calls
126*b1cdbd2cSJim Jagielski             they must be accompanied by an equal number of calls to ->resumeAutoFire, to enable
127*b1cdbd2cSJim Jagielski             auto-firing again.
128*b1cdbd2cSJim Jagielski 
129*b1cdbd2cSJim Jagielski             @seealso resumeAutoFire
130*b1cdbd2cSJim Jagielski         */
131*b1cdbd2cSJim Jagielski         void SAL_CALL suspendAutoFire();
132*b1cdbd2cSJim Jagielski 
133*b1cdbd2cSJim Jagielski         /** Suspends automatic firing of UI changes
134*b1cdbd2cSJim Jagielski 
135*b1cdbd2cSJim Jagielski             @seealso suspendAutoFire
136*b1cdbd2cSJim Jagielski         */
137*b1cdbd2cSJim Jagielski         void SAL_CALL resumeAutoFire();
138*b1cdbd2cSJim Jagielski 
139*b1cdbd2cSJim Jagielski         /** disposes the instance, so it becomes non-functional.
140*b1cdbd2cSJim Jagielski 
141*b1cdbd2cSJim Jagielski             All cached handlers and cached ->XObjectInspectorUI instances will be released,
142*b1cdbd2cSJim Jagielski             the latter will also be disposed, so that if anybody still holds a reference to them
143*b1cdbd2cSJim Jagielski             and tries to operate them will get a DisposedException.
144*b1cdbd2cSJim Jagielski         */
145*b1cdbd2cSJim Jagielski         void SAL_CALL dispose();
146*b1cdbd2cSJim Jagielski 
147*b1cdbd2cSJim Jagielski         /** invokes m_pPropertyCheck to check whether a given property should be handled
148*b1cdbd2cSJim Jagielski         */
149*b1cdbd2cSJim Jagielski         bool shouldContinuePropertyHandling( const ::rtl::OUString& _rName ) const;
150*b1cdbd2cSJim Jagielski 
151*b1cdbd2cSJim Jagielski     private:
152*b1cdbd2cSJim Jagielski         /// determines whether the instance is already disposed
impl_isDisposed() const153*b1cdbd2cSJim Jagielski         inline  bool impl_isDisposed() const { return m_pCollectedUIs.get() == NULL; }
154*b1cdbd2cSJim Jagielski 
155*b1cdbd2cSJim Jagielski         /// throws an exception if the component is already disposed
156*b1cdbd2cSJim Jagielski                 void impl_checkDisposed() const;
157*b1cdbd2cSJim Jagielski 
158*b1cdbd2cSJim Jagielski         /** fires the collected UI changes to our delegator UI
159*b1cdbd2cSJim Jagielski 
160*b1cdbd2cSJim Jagielski             All operations for any elements are forwarded:
161*b1cdbd2cSJim Jagielski             <ul><li>If an element has been hidden at least once, it's also hidden at the delegator UI.</li>
162*b1cdbd2cSJim Jagielski                 <li>If an element has been shown at least once, and never been hidden, it's also
163*b1cdbd2cSJim Jagielski                     shown at the delegator UI.</li>
164*b1cdbd2cSJim Jagielski                 <li>If an element has never been shown or hidden, it's also not touched at the delegator UI.</li>
165*b1cdbd2cSJim Jagielski                 <li>The same holds if you replace "hidden" in the last three items with "disabled",
166*b1cdbd2cSJim Jagielski                     and "shown" with "enabled".</li>
167*b1cdbd2cSJim Jagielski                 <li>If an element should have been rebuilt (->XObjectInspectorUI::rebuiltPropertyUI)
168*b1cdbd2cSJim Jagielski                     at least once, it's rebuilt at the delegator UI, too.<br/>
169*b1cdbd2cSJim Jagielski                     After that, the request to rebuild the UI for this property is cleared, so subsequent
170*b1cdbd2cSJim Jagielski                     calls to ->fire will not trigger an new rebuilt request.
171*b1cdbd2cSJim Jagielski             </ul>
172*b1cdbd2cSJim Jagielski 
173*b1cdbd2cSJim Jagielski             @precond
174*b1cdbd2cSJim Jagielski                 instance is not disposed
175*b1cdbd2cSJim Jagielski         */
176*b1cdbd2cSJim Jagielski         void    impl_fireAll_throw();
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski         /// fires the combination of ->XObjectInspectorUI::enablePropertyUI calls
179*b1cdbd2cSJim Jagielski         void    impl_fireEnablePropertyUI_throw();
180*b1cdbd2cSJim Jagielski 
181*b1cdbd2cSJim Jagielski         /// fires the combination of ->XObjectInspectorUI::enablePropertyUIElements calls
182*b1cdbd2cSJim Jagielski         void    impl_fireEnablePropertyUIElements_throw();
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski         /// fires the combination of ->XObjectInspectorUI::rebuildPropertyUI calls
185*b1cdbd2cSJim Jagielski         void    impl_fireRebuildPropertyUI_throw();
186*b1cdbd2cSJim Jagielski 
187*b1cdbd2cSJim Jagielski         /// fires the combination of ->XObjectInspectorUI::showPropertyUI and ->XObjectInspectorUI::hidePropertyUI calls
188*b1cdbd2cSJim Jagielski         void    impl_fireShowHidePropertyUI_throw();
189*b1cdbd2cSJim Jagielski 
190*b1cdbd2cSJim Jagielski         /// fires the combination of ->XObjectInspectorUI::showCategory calls
191*b1cdbd2cSJim Jagielski         void    impl_fireShowCategory_throw();
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski         /** callback for when a single property handler requested any change in the inspector UI
194*b1cdbd2cSJim Jagielski         */
195*b1cdbd2cSJim Jagielski         void    callback_inspectorUIChanged_throw();
196*b1cdbd2cSJim Jagielski 
197*b1cdbd2cSJim Jagielski     private:
198*b1cdbd2cSJim Jagielski         ComposedPropertyUIUpdate();                                             // never implemented
199*b1cdbd2cSJim Jagielski         ComposedPropertyUIUpdate( const ComposedPropertyUIUpdate& );            // never implemented
200*b1cdbd2cSJim Jagielski         ComposedPropertyUIUpdate& operator=( const ComposedPropertyUIUpdate& ); // never implemented
201*b1cdbd2cSJim Jagielski     };
202*b1cdbd2cSJim Jagielski 
203*b1cdbd2cSJim Jagielski     //====================================================================
204*b1cdbd2cSJim Jagielski 	//= ComposedUIAutoFireGuard
205*b1cdbd2cSJim Jagielski 	//====================================================================
206*b1cdbd2cSJim Jagielski     class ComposedUIAutoFireGuard
207*b1cdbd2cSJim Jagielski     {
208*b1cdbd2cSJim Jagielski     private:
209*b1cdbd2cSJim Jagielski         ComposedPropertyUIUpdate&   m_rUIUpdate;
210*b1cdbd2cSJim Jagielski     public:
ComposedUIAutoFireGuard(ComposedPropertyUIUpdate & _rUIUpdate)211*b1cdbd2cSJim Jagielski         ComposedUIAutoFireGuard( ComposedPropertyUIUpdate& _rUIUpdate )
212*b1cdbd2cSJim Jagielski             :m_rUIUpdate( _rUIUpdate )
213*b1cdbd2cSJim Jagielski         {
214*b1cdbd2cSJim Jagielski             m_rUIUpdate.suspendAutoFire();
215*b1cdbd2cSJim Jagielski         }
~ComposedUIAutoFireGuard()216*b1cdbd2cSJim Jagielski         ~ComposedUIAutoFireGuard()
217*b1cdbd2cSJim Jagielski         {
218*b1cdbd2cSJim Jagielski             m_rUIUpdate.resumeAutoFire();
219*b1cdbd2cSJim Jagielski         }
220*b1cdbd2cSJim Jagielski     };
221*b1cdbd2cSJim Jagielski 
222*b1cdbd2cSJim Jagielski //........................................................................
223*b1cdbd2cSJim Jagielski } // namespace pcr
224*b1cdbd2cSJim Jagielski //........................................................................
225*b1cdbd2cSJim Jagielski 
226*b1cdbd2cSJim Jagielski #endif // EXTENSIONS_SOURCE_PROPCTRLR_COMPOSEDUIUPDATE_HXX
227*b1cdbd2cSJim Jagielski 
228