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 SVTOOLS_DIALOGCONTROLLING_HXX 25 #define SVTOOLS_DIALOGCONTROLLING_HXX 26 27 #include <svtools/svtdllapi.h> 28 29 #include <tools/link.hxx> 30 #include <vcl/button.hxx> 31 32 #include <vector> 33 #include <boost/shared_ptr.hpp> 34 35 //........................................................................ 36 namespace svt 37 { 38 //........................................................................ 39 40 //===================================================================== 41 //= IWindowOperator 42 //===================================================================== 43 /** an abstract interface for operating on a ->Window 44 */ 45 class SVT_DLLPUBLIC SAL_NO_VTABLE IWindowOperator 46 { 47 public: 48 /** called when an event happened which should be reacted to 49 50 @param _rTrigger 51 the event which triggered the call. If the Id of the event is 0, then this is the initial 52 call which is made when ->_rOperateOn is added to the responsibility of the DialogController. 53 @param _rOperateOn 54 the window on which to operate 55 */ 56 virtual void operateOn( const VclWindowEvent& _rTrigger, Window& _rOperateOn ) const = 0; 57 58 virtual ~IWindowOperator(); 59 }; 60 typedef ::boost::shared_ptr< IWindowOperator > PWindowOperator; 61 62 //===================================================================== 63 //= IWindowEventFilter 64 //===================================================================== 65 /** an abstract interface for deciding whether a ->VclWindowEvent 66 is worth paying attention to 67 */ 68 class SVT_DLLPUBLIC SAL_NO_VTABLE IWindowEventFilter 69 { 70 public: 71 virtual bool payAttentionTo( const VclWindowEvent& _rEvent ) const = 0; 72 73 virtual ~IWindowEventFilter(); 74 }; 75 typedef ::boost::shared_ptr< IWindowEventFilter > PWindowEventFilter; 76 77 //===================================================================== 78 //= DialogController 79 //===================================================================== 80 struct DialogController_Data; 81 /** a class controlling interactions between dialog controls 82 83 An instance of this class listens to all events fired by a certain 84 ->Control (more precise, a ->Window), the so-called instigator. 85 86 Additionally, the ->DialogController maintains a list of windows which 87 are affected by changes in the instigator window. Let's call those the 88 dependent windows. 89 90 Now, by help of an owner-provided ->IWindowEventFilter, the ->DialogController 91 decides which events are worth attention. By help of an owner-provided 92 ->IWindowOperator, it handles those events for all dependent windows. 93 */ 94 class SVT_DLLPUBLIC DialogController 95 { 96 private: 97 ::std::auto_ptr< DialogController_Data > m_pImpl; 98 99 public: 100 DialogController( Window& _rInstigator, const PWindowEventFilter& _pEventFilter, const PWindowOperator& _pOperator ); 101 virtual ~DialogController(); 102 103 /** adds a window to the list of dependent windows 104 105 @param _rWindow 106 The window to add to the list of dependent windows. 107 108 The caller is responsible for life-time control: The given window 109 must live at least as long as the ->DialogController instance does. 110 */ 111 void addDependentWindow( Window& _rWindow ); 112 113 /** resets the controller so that no actions happened anymore. 114 115 The instances is disfunctional after this method has been called. 116 */ 117 void reset(); 118 119 private: 120 void impl_Init(); 121 void impl_updateAll( const VclWindowEvent& _rTriggerEvent ); 122 void impl_update( const VclWindowEvent& _rTriggerEvent, Window& _rWindow ); 123 124 DECL_LINK( OnWindowEvent, const VclWindowEvent* ); 125 126 private: 127 DialogController( const DialogController& ); // never implemented 128 DialogController& operator=( const DialogController& ); // never implemented 129 }; 130 typedef ::boost::shared_ptr< DialogController > PDialogController; 131 132 //===================================================================== 133 //= ControlDependencyManager 134 //===================================================================== 135 struct ControlDependencyManager_Data; 136 /** helper class for managing control dependencies 137 138 Instances of this class are intended to be held as members of a dialog/tabpage/whatever 139 class, with easy administration of inter-control dependencies (such as "Enable 140 control X if and only if checkbox Y is checked). 141 */ 142 class SVT_DLLPUBLIC ControlDependencyManager 143 { 144 private: 145 ::std::auto_ptr< ControlDependencyManager_Data > m_pImpl; 146 147 public: 148 ControlDependencyManager(); 149 ~ControlDependencyManager(); 150 151 /** clears all dialog controllers previously added to the manager 152 */ 153 void clear(); 154 155 /** ensures that a given window is enabled or disabled, according to the check state 156 of a given radio button 157 @param _rRadio 158 denotes the radio button whose check state is to observe 159 @param _rDependentWindow 160 denotes the window which should be enabled when ->_rRadio is checked, and 161 disabled when it's unchecked 162 */ 163 void enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow ); 164 void enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2 ); 165 void enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3 ); 166 void enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4 ); 167 void enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5 ); 168 void enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5, Window& _rDependentWindow6 ); 169 170 /** ensures that a given window is enabled or disabled, according to the mark state 171 of a given check box 172 @param _rBox 173 denotes the check box whose mark state is to observe 174 @param _rDependentWindow 175 denotes the window which should be enabled when ->_rBox is marked, and 176 disabled when it's unmarked 177 */ 178 void enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow ); 179 void enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2 ); 180 void enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3 ); 181 void enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4 ); 182 void enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5 ); 183 void enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5, Window& _rDependentWindow6 ); 184 185 /** adds a non-standard controller whose functionality is not covered by the other methods 186 187 @param _pController 188 the controller to add to the manager. Must not be <NULL/>. 189 */ 190 void addController( const PDialogController& _pController ); 191 192 private: 193 ControlDependencyManager( const ControlDependencyManager& ); // never implemented 194 ControlDependencyManager& operator=( const ControlDependencyManager& ); // never implemented 195 }; 196 197 //===================================================================== 198 //= EnableOnCheck 199 //===================================================================== 200 /** a helper class implementing the ->IWindowOperator interface, 201 which enables a dependent window depending on the check state of 202 an instigator window. 203 204 @see DialogController 205 */ 206 template< class CHECKABLE > 207 class SVT_DLLPUBLIC EnableOnCheck : public IWindowOperator 208 { 209 public: 210 typedef CHECKABLE SourceType; 211 212 private: 213 SourceType& m_rCheckable; 214 215 public: 216 /** constructs the instance 217 218 @param _rCheckable 219 a ->Window instance which supports a boolean method IsChecked. Usually 220 a ->RadioButton or ->CheckBox 221 */ EnableOnCheck(SourceType & _rCheckable)222 EnableOnCheck( SourceType& _rCheckable ) 223 :m_rCheckable( _rCheckable ) 224 { 225 } 226 operateOn(const VclWindowEvent &,Window & _rOperateOn) const227 virtual void operateOn( const VclWindowEvent& /*_rTrigger*/, Window& _rOperateOn ) const 228 { 229 _rOperateOn.Enable( m_rCheckable.IsChecked() ); 230 } 231 }; 232 233 //===================================================================== 234 //= FilterForRadioOrCheckToggle 235 //===================================================================== 236 /** a helper class implementing the ->IWindowEventFilter interface, 237 which filters for radio buttons or check boxes being toggled. 238 239 Technically, the class simply filters for the ->VCLEVENT_RADIOBUTTON_TOGGLE 240 and the ->VCLEVENT_CHECKBOX_TOGGLE event. 241 */ 242 class SVT_DLLPUBLIC FilterForRadioOrCheckToggle : public IWindowEventFilter 243 { 244 const Window& m_rWindow; 245 public: FilterForRadioOrCheckToggle(const Window & _rWindow)246 FilterForRadioOrCheckToggle( const Window& _rWindow ) 247 :m_rWindow( _rWindow ) 248 { 249 } 250 payAttentionTo(const VclWindowEvent & _rEvent) const251 bool payAttentionTo( const VclWindowEvent& _rEvent ) const 252 { 253 if ( ( _rEvent.GetWindow() == &m_rWindow ) 254 && ( ( _rEvent.GetId() == VCLEVENT_RADIOBUTTON_TOGGLE ) 255 || ( _rEvent.GetId() == VCLEVENT_CHECKBOX_TOGGLE ) 256 ) 257 ) 258 return true; 259 return false; 260 } 261 }; 262 263 //===================================================================== 264 //= RadioDependentEnabler 265 //===================================================================== 266 /** a ->DialogController derivee which enables or disables its dependent windows, 267 depending on the check state of a radio button. 268 269 The usage of this class is as simple as 270 <code> 271 pController = new RadioDependentEnabler( m_aOptionSelectSomething ); 272 pController->addDependentWindow( m_aLabelSelection ); 273 pController->addDependentWindow( m_aListSelection ); 274 </code> 275 276 With this, both <code>m_aLabelSelection</code> and <code>m_aListSelection</code> will 277 be disabled if and only <code>m_aOptionSelectSomething</code> is checked. 278 */ 279 class SVT_DLLPUBLIC RadioDependentEnabler : public DialogController 280 { 281 public: RadioDependentEnabler(RadioButton & _rButton)282 RadioDependentEnabler( RadioButton& _rButton ) 283 :DialogController( _rButton, 284 PWindowEventFilter( new FilterForRadioOrCheckToggle( _rButton ) ), 285 PWindowOperator( new EnableOnCheck< RadioButton >( _rButton ) ) ) 286 { 287 } 288 RadioDependentEnabler(CheckBox & _rBox)289 RadioDependentEnabler( CheckBox& _rBox ) 290 :DialogController( _rBox, 291 PWindowEventFilter( new FilterForRadioOrCheckToggle( _rBox ) ), 292 PWindowOperator( new EnableOnCheck< CheckBox >( _rBox ) ) ) 293 { 294 } 295 }; 296 297 //........................................................................ 298 } // namespace svt 299 //........................................................................ 300 301 #endif // SVTOOLS_DIALOGCONTROLLING_HXX 302 303