summaryrefslogtreecommitdiff
path: root/svtools/inc/dialogcontrolling.hxx
blob: cd60736527f5ee5649530cedc43372a0534aff87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SVTOOLS_DIALOGCONTROLLING_HXX
#define SVTOOLS_DIALOGCONTROLLING_HXX

#include <svtools/svtdllapi.h>

#include <tools/link.hxx>
#include <vcl/button.hxx>

#include <vector>
#include <boost/shared_ptr.hpp>

//........................................................................
namespace svt
{
//........................................................................

    //=====================================================================
    //= IWindowOperator
    //=====================================================================
    /** an abstract interface for operating on a ->Window
    */
    class SVT_DLLPUBLIC SAL_NO_VTABLE IWindowOperator
    {
    public:
        /** called when an event happened which should be reacted to

            @param _rTrigger
                the event which triggered the call. If the Id of the event is 0, then this is the initial
                call which is made when ->_rOperateOn is added to the responsibility of the DialogController.
            @param _rOperateOn
                the window on which to operate
        */
        virtual void operateOn( const VclWindowEvent& _rTrigger, Window& _rOperateOn ) const = 0;

        virtual ~IWindowOperator();
    };
    typedef ::boost::shared_ptr< IWindowOperator >  PWindowOperator;

    //=====================================================================
    //= IWindowEventFilter
    //=====================================================================
    /** an abstract interface for deciding whether a ->VclWindowEvent
        is worth paying attention to
    */
    class SVT_DLLPUBLIC SAL_NO_VTABLE IWindowEventFilter
    {
    public:
        virtual bool payAttentionTo( const VclWindowEvent& _rEvent ) const = 0;

        virtual ~IWindowEventFilter();
    };
    typedef ::boost::shared_ptr< IWindowEventFilter >   PWindowEventFilter;

    //=====================================================================
    //= DialogController
    //=====================================================================
    struct DialogController_Data;
    /** a class controlling interactions between dialog controls

        An instance of this class listens to all events fired by a certain
        ->Control (more precise, a ->Window), the so-called instigator.

        Additionally, the ->DialogController maintains a list of windows which
        are affected by changes in the instigator window. Let's call those the
        dependent windows.

        Now, by help of an owner-provided ->IWindowEventFilter, the ->DialogController
        decides which events are worth attention. By help of an owner-provided
        ->IWindowOperator, it handles those events for all dependent windows.
    */
    class SVT_DLLPUBLIC DialogController
    {
    private:
        ::std::auto_ptr< DialogController_Data >    m_pImpl;

    public:
        DialogController( Window& _rInstigator, const PWindowEventFilter& _pEventFilter, const PWindowOperator& _pOperator );
        virtual ~DialogController();

        /** adds a window to the list of dependent windows

            @param _rWindow
                The window to add to the list of dependent windows.

                The caller is responsible for life-time control: The given window
                must live at least as long as the ->DialogController instance does.
        */
        void    addDependentWindow( Window& _rWindow );

        /** resets the controller so that no actions happend anymore.

            The instances is disfunctional after this method has been called.
        */
        void    reset();

    private:
        void    impl_Init();
        void    impl_updateAll( const VclWindowEvent& _rTriggerEvent );
        void    impl_update( const VclWindowEvent& _rTriggerEvent, Window& _rWindow );

        DECL_LINK( OnWindowEvent, const VclWindowEvent* );

    private:
        DialogController( const DialogController& );            // never implemented
        DialogController& operator=( const DialogController& ); // never implemented
    };
    typedef ::boost::shared_ptr< DialogController > PDialogController;

    //=====================================================================
    //= ControlDependencyManager
    //=====================================================================
    struct ControlDependencyManager_Data;
    /** helper class for managing control dependencies

        Instances of this class are intended to be held as members of a dialog/tabpage/whatever
        class, with easy administration of inter-control dependencies (such as "Enable
        control X if and only if checkbox Y is checked).
    */
    class SVT_DLLPUBLIC ControlDependencyManager
    {
    private:
        ::std::auto_ptr< ControlDependencyManager_Data >    m_pImpl;

    public:
        ControlDependencyManager();
        ~ControlDependencyManager();

        /** clears all dialog controllers previously added to the manager
        */
        void    clear();

        /** ensures that a given window is enabled or disabled, according to the check state
            of a given radio button
            @param _rRadio
                denotes the radio button whose check state is to observe
            @param _rDependentWindow
                denotes the window which should be enabled when ->_rRadio is checked, and
                disabled when it's unchecked
        */
        void    enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow );
        void    enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2 );
        void    enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3 );
        void    enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4 );
        void    enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5 );
        void    enableOnRadioCheck( RadioButton& _rRadio, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5, Window& _rDependentWindow6 );

        /** ensures that a given window is enabled or disabled, according to the mark state
            of a given check box
            @param _rBox
                denotes the check box whose mark state is to observe
            @param _rDependentWindow
                denotes the window which should be enabled when ->_rBox is marked, and
                disabled when it's unmarked
        */
        void    enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow );
        void    enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2 );
        void    enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3 );
        void    enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4 );
        void    enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5 );
        void    enableOnCheckMark( CheckBox& _rBox, Window& _rDependentWindow1, Window& _rDependentWindow2, Window& _rDependentWindow3, Window& _rDependentWindow4, Window& _rDependentWindow5, Window& _rDependentWindow6 );

        /** adds a non-standard controller whose functionality is not covered by the other methods

            @param _pController
                the controller to add to the manager. Must not be <NULL/>.
        */
        void    addController( const PDialogController& _pController );

    private:
        ControlDependencyManager( const ControlDependencyManager& );            // never implemented
        ControlDependencyManager& operator=( const ControlDependencyManager& ); // never implemented
    };

    //=====================================================================
    //= EnableOnCheck
    //=====================================================================
    /** a helper class implementing the ->IWindowOperator interface,
        which enables a dependent window depending on the check state of
        an instigator window.

        @see DialogController
    */
    template< class CHECKABLE >
    class SVT_DLLPUBLIC EnableOnCheck : public IWindowOperator
    {
    public:
        typedef CHECKABLE   SourceType;

    private:
        SourceType& m_rCheckable;

    public:
        /** constructs the instance

            @param _rCheckable
                a ->Window instance which supports a boolean method IsChecked. Usually
                a ->RadioButton or ->CheckBox
        */
        EnableOnCheck( SourceType& _rCheckable )
            :m_rCheckable( _rCheckable )
        {
        }

        virtual void operateOn( const VclWindowEvent& /*_rTrigger*/, Window& _rOperateOn ) const
        {
            _rOperateOn.Enable( m_rCheckable.IsChecked() );
        }
    };

    //=====================================================================
    //= FilterForRadioOrCheckToggle
    //=====================================================================
    /** a helper class implementing the ->IWindowEventFilter interface,
        which filters for radio buttons or check boxes being toggled.

        Technically, the class simply filters for the ->VCLEVENT_RADIOBUTTON_TOGGLE
        and the ->VCLEVENT_CHECKBOX_TOGGLE event.
    */
    class SVT_DLLPUBLIC FilterForRadioOrCheckToggle : public IWindowEventFilter
    {
        const Window&   m_rWindow;
    public:
        FilterForRadioOrCheckToggle( const Window& _rWindow )
            :m_rWindow( _rWindow )
        {
        }

        bool payAttentionTo( const VclWindowEvent& _rEvent ) const
        {
            if  (   ( _rEvent.GetWindow() == &m_rWindow )
                &&  (   ( _rEvent.GetId() == VCLEVENT_RADIOBUTTON_TOGGLE )
                    ||  ( _rEvent.GetId() == VCLEVENT_CHECKBOX_TOGGLE )
                    )
                )
                return true;
            return false;
        }
    };

    //=====================================================================
    //= RadioDependentEnabler
    //=====================================================================
    /** a ->DialogController derivee which enables or disables its dependent windows,
        depending on the check state of a radio button.

        The usage of this class is as simple as
        <code>
        pController = new RadioDependentEnabler( m_aOptionSelectSomething );
        pController->addDependentWindow( m_aLabelSelection );
        pController->addDependentWindow( m_aListSelection );
        </code>

        With this, both <code>m_aLabelSelection</code> and <code>m_aListSelection</code> will
        be disabled if and only <code>m_aOptionSelectSomething</code> is checked.
    */
    class SVT_DLLPUBLIC RadioDependentEnabler : public DialogController
    {
    public:
        RadioDependentEnabler( RadioButton& _rButton )
            :DialogController( _rButton,
                PWindowEventFilter( new FilterForRadioOrCheckToggle( _rButton ) ),
                PWindowOperator( new EnableOnCheck< RadioButton >( _rButton ) ) )
        {
        }

        RadioDependentEnabler( CheckBox& _rBox )
            :DialogController( _rBox,
                PWindowEventFilter( new FilterForRadioOrCheckToggle( _rBox ) ),
                PWindowOperator( new EnableOnCheck< CheckBox >( _rBox ) ) )
        {
        }
    };

//........................................................................
} // namespace svt
//........................................................................

#endif // SVTOOLS_DIALOGCONTROLLING_HXX