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