~ubuntu-branches/ubuntu/utopic/python-traitsui/utopic

« back to all changes in this revision

Viewing changes to traitsui/wx/check_list_editor.py

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2011-07-09 13:57:39 UTC
  • Revision ID: james.westby@ubuntu.com-20110709135739-x5u20q86huissmn1
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#------------------------------------------------------------------------------
 
2
#
 
3
#  Copyright (c) 2005, Enthought, Inc.
 
4
#  All rights reserved.
 
5
#
 
6
#  This software is provided without warranty under the terms of the BSD
 
7
#  license included in enthought/LICENSE.txt and may be redistributed only
 
8
#  under the conditions described in the aforementioned license.  The license
 
9
#  is also available online at http://www.enthought.com/licenses/BSD.txt
 
10
#
 
11
#  Thanks for using Enthought open source!
 
12
#
 
13
#  Author: David C. Morrill
 
14
#  Date:   10/21/2004
 
15
#
 
16
#------------------------------------------------------------------------------
 
17
 
 
18
""" Defines the various editors for multi-selection enumerations, for the
 
19
wxPython user interface toolkit.
 
20
"""
 
21
 
 
22
#-------------------------------------------------------------------------------
 
23
#  Imports:
 
24
#-------------------------------------------------------------------------------
 
25
 
 
26
import logging
 
27
 
 
28
import wx
 
29
 
 
30
from string \
 
31
    import capitalize
 
32
 
 
33
from traits.api \
 
34
    import List, Str, TraitError
 
35
 
 
36
# FIXME: ToolkitEditorFactory is a proxy class defined here just for backward
 
37
# compatibility. The class has been moved to the
 
38
# traitsui.editors.check_list_editor file.
 
39
from traitsui.editors.check_list_editor \
 
40
    import ToolkitEditorFactory
 
41
 
 
42
from editor_factory \
 
43
    import TextEditor as BaseTextEditor
 
44
 
 
45
from editor \
 
46
    import EditorWithList
 
47
 
 
48
from helper \
 
49
    import TraitsUIPanel
 
50
 
 
51
logger = logging.getLogger(__name__)
 
52
 
 
53
#-------------------------------------------------------------------------------
 
54
#  'SimpleEditor' class:
 
55
#-------------------------------------------------------------------------------
 
56
 
 
57
class SimpleEditor ( EditorWithList ):
 
58
    """ Simple style of editor for checklists, which displays a combo box.
 
59
    """
 
60
 
 
61
    #---------------------------------------------------------------------------
 
62
    #  Trait definitions:
 
63
    #---------------------------------------------------------------------------
 
64
 
 
65
    # Checklist item names
 
66
    names = List( Str )
 
67
 
 
68
    # Checklist item values
 
69
    values = List
 
70
 
 
71
    #---------------------------------------------------------------------------
 
72
    #  Finishes initializing the editor by creating the underlying toolkit
 
73
    #  widget:
 
74
    #---------------------------------------------------------------------------
 
75
 
 
76
    def init ( self, parent ):
 
77
        """ Finishes initializing the editor by creating the underlying toolkit
 
78
            widget.
 
79
        """
 
80
        self.create_control( parent )
 
81
        super( SimpleEditor, self ).init( parent )
 
82
        self.set_tooltip()
 
83
 
 
84
    #---------------------------------------------------------------------------
 
85
    #  Creates the initial editor control:
 
86
    #---------------------------------------------------------------------------
 
87
 
 
88
    def create_control ( self, parent ):
 
89
        """ Creates the initial editor control.
 
90
        """
 
91
        self.control = wx.Choice( parent, -1,
 
92
                                  wx.Point( 0, 0 ), wx.Size( 100, 20 ), [] )
 
93
        wx.EVT_CHOICE( parent, self.control.GetId(), self.update_object )
 
94
 
 
95
    #---------------------------------------------------------------------------
 
96
    #  Handles the list of legal check list values being updated:
 
97
    #---------------------------------------------------------------------------
 
98
 
 
99
    def list_updated ( self, values ):
 
100
        """ Handles updates to the list of legal checklist values.
 
101
        """
 
102
        sv = self.string_value
 
103
        if (len( values ) > 0) and isinstance( values[0], basestring ):
 
104
           values = [ ( x, sv( x, capitalize ) ) for x in values ]
 
105
        self.values = valid_values = [ x[0] for x in values ]
 
106
        self.names  =                [ x[1] for x in values ]
 
107
 
 
108
        # Make sure the current value is still legal:
 
109
        modified  = False
 
110
        cur_value = parse_value( self.value )
 
111
        for i in range( len( cur_value ) - 1, -1, -1 ):
 
112
            if cur_value[i] not in valid_values:
 
113
                try:
 
114
                    del cur_value[i]
 
115
                    modified = True
 
116
                except TypeError, e:
 
117
                    logger.warn('Unable to remove non-current value [%s] from '
 
118
                        'values %s', cur_value[i], values)
 
119
        if modified:
 
120
            if isinstance( self.value, basestring ):
 
121
                cur_value = ','.join( cur_value )
 
122
            self.value = cur_value
 
123
 
 
124
        self.rebuild_editor()
 
125
 
 
126
    #---------------------------------------------------------------------------
 
127
    #  Rebuilds the editor after its definition is modified:
 
128
    #---------------------------------------------------------------------------
 
129
 
 
130
    def rebuild_editor ( self ):
 
131
        """ Rebuilds the editor after its definition is modified.
 
132
        """
 
133
        control = self.control
 
134
        control.Clear()
 
135
        for name in self.names:
 
136
            control.Append( name )
 
137
 
 
138
        self.update_editor()
 
139
 
 
140
    #----------------------------------------------------------------------------
 
141
    #  Handles the user selecting a new value from the combo box:
 
142
    #----------------------------------------------------------------------------
 
143
 
 
144
    def update_object ( self, event ):
 
145
        """ Handles the user selecting a new value from the combo box.
 
146
        """
 
147
        value = self.values[ self.names.index( event.GetString() ) ]
 
148
        if type( self.value ) is not str:
 
149
           value = [ value ]
 
150
 
 
151
        self.value = value
 
152
 
 
153
    #---------------------------------------------------------------------------
 
154
    #  Updates the editor when the object trait changes external to the editor:
 
155
    #---------------------------------------------------------------------------
 
156
 
 
157
    def update_editor ( self ):
 
158
        """ Updates the editor when the object trait changes externally to the
 
159
            editor.
 
160
        """
 
161
        try:
 
162
            self.control.SetSelection(
 
163
                             self.values.index( parse_value( self.value )[0] ) )
 
164
        except:
 
165
            pass
 
166
 
 
167
#-------------------------------------------------------------------------------
 
168
#  'CustomEditor' class:
 
169
#-------------------------------------------------------------------------------
 
170
 
 
171
class CustomEditor ( SimpleEditor ):
 
172
    """ Custom style of editor for checklists, which displays a set of check
 
173
        boxes.
 
174
    """
 
175
 
 
176
    #---------------------------------------------------------------------------
 
177
    #  Creates the initial editor control:
 
178
    #---------------------------------------------------------------------------
 
179
 
 
180
    def create_control ( self, parent ):
 
181
        """ Creates the initial editor control.
 
182
        """
 
183
        # Create a panel to hold all of the check boxes
 
184
        self.control = panel = TraitsUIPanel( parent, -1 )
 
185
 
 
186
    #---------------------------------------------------------------------------
 
187
    #  Rebuilds the editor after its definition is modified:
 
188
    #---------------------------------------------------------------------------
 
189
 
 
190
    def rebuild_editor ( self ):
 
191
        """ Rebuilds the editor after its definition is modified.
 
192
        """
 
193
        panel = self.control
 
194
        panel.SetSizer( None )
 
195
        panel.DestroyChildren()
 
196
 
 
197
        cur_value = parse_value( self.value )
 
198
 
 
199
        # Create a sizer to manage the radio buttons:
 
200
        labels = self.names
 
201
        values = self.values
 
202
        n      = len( labels )
 
203
        cols   = self.factory.cols
 
204
        rows   = (n + cols - 1) / cols
 
205
        incr   = [ n / cols ] * cols
 
206
        rem    = n % cols
 
207
 
 
208
        for i in range( cols ):
 
209
            incr[i] += (rem > i)
 
210
        incr[-1] = -(reduce( lambda x, y: x + y, incr[:-1], 0 ) - 1)
 
211
 
 
212
        if cols > 1:
 
213
           sizer = wx.GridSizer( 0, cols, 2, 4 )
 
214
        else:
 
215
           sizer = wx.BoxSizer( wx.VERTICAL )
 
216
 
 
217
        # Add the set of all possible choices:
 
218
        index = 0
 
219
        for i in range( rows ):
 
220
            for j in range( cols ):
 
221
                if n > 0:
 
222
                    label   = labels[ index ]
 
223
                    control = wx.CheckBox( panel, -1, label )
 
224
                    control.value = value = values[ index ]
 
225
                    control.SetValue( value in cur_value )
 
226
                    wx.EVT_CHECKBOX( panel, control.GetId(), self.update_object)
 
227
                    index += incr[j]
 
228
                    n     -= 1
 
229
                else:
 
230
                    control = wx.CheckBox( panel, -1, '' )
 
231
                    control.Show( False )
 
232
 
 
233
                sizer.Add( control, 0, wx.NORTH, 5 )
 
234
 
 
235
        # Lay out the controls:
 
236
        panel.SetSizerAndFit( sizer )
 
237
 
 
238
        # FIXME: There are cases where one of the parent panel's of the check
 
239
        # list editor has a fixed 'min size' which prevents the check list
 
240
        # editor from expanding correctly, so we currently are making sure
 
241
        # that all of the parent panels do not have a fixed min size before
 
242
        # doing the layout/refresh:
 
243
        parent = panel.GetParent()
 
244
        while isinstance( parent, wx.Panel ):
 
245
            parent.SetMinSize( wx.Size( -1, -1 ) )
 
246
            panel  = parent
 
247
            parent = parent.GetParent()
 
248
 
 
249
        panel.Layout()
 
250
        panel.Refresh()
 
251
 
 
252
    #---------------------------------------------------------------------------
 
253
    #  Handles the user clicking one of the 'custom' check boxes:
 
254
    #---------------------------------------------------------------------------
 
255
 
 
256
    def update_object ( self, event ):
 
257
        """ Handles the user clicking one of the custom check boxes.
 
258
        """
 
259
        control   = event.GetEventObject()
 
260
        cur_value = parse_value( self.value )
 
261
        if control.GetValue():
 
262
            cur_value.append( control.value )
 
263
        else:
 
264
            cur_value.remove( control.value )
 
265
        if isinstance(self.value, basestring):
 
266
            cur_value = ','.join( cur_value )
 
267
        self.value = cur_value
 
268
 
 
269
    #---------------------------------------------------------------------------
 
270
    #  Updates the editor when the object trait changes external to the editor:
 
271
    #---------------------------------------------------------------------------
 
272
 
 
273
    def update_editor ( self ):
 
274
        """ Updates the editor when the object trait changes externally to the
 
275
            editor.
 
276
        """
 
277
        new_values = parse_value( self.value )
 
278
        for control in self.control.GetChildren():
 
279
            if control.IsShown():
 
280
               control.SetValue( control.value in new_values )
 
281
 
 
282
#-------------------------------------------------------------------------------
 
283
#  'TextEditor' class:
 
284
#-------------------------------------------------------------------------------
 
285
 
 
286
class TextEditor ( BaseTextEditor ):
 
287
    """ Text style of editor for checklists, which displays a text field.
 
288
    """
 
289
 
 
290
    #---------------------------------------------------------------------------
 
291
    #  Handles the user changing the contents of the edit control:
 
292
    #---------------------------------------------------------------------------
 
293
 
 
294
    def update_object ( self, event ):
 
295
        """ Handles the user changing the contents of the edit control.
 
296
        """
 
297
        try:
 
298
            value = self.control.GetValue()
 
299
            value = eval( value )
 
300
        except:
 
301
            pass
 
302
        try:
 
303
            self.value = value
 
304
        except TraitError, excp:
 
305
            pass
 
306
 
 
307
#-------------------------------------------------------------------------------
 
308
#  Parse a value into a list:
 
309
#-------------------------------------------------------------------------------
 
310
 
 
311
def parse_value ( value ):
 
312
    """ Parses a value into a list.
 
313
    """
 
314
    if value is None:
 
315
       return []
 
316
 
 
317
    if type( value ) is not str:
 
318
       return value[:]
 
319
 
 
320
    return [ x.strip() for x in value.split( ',' ) ]
 
321
 
 
322
### EOF ########################################################################
 
323