1
#------------------------------------------------------------------------------
3
# Copyright (c) 2005, Enthought, Inc.
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
11
# Thanks for using Enthought open source!
13
# Author: David C. Morrill
16
#------------------------------------------------------------------------------
18
""" Defines the various editors for multi-selection enumerations, for the
19
wxPython user interface toolkit.
22
#-------------------------------------------------------------------------------
24
#-------------------------------------------------------------------------------
34
import List, Str, TraitError
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
43
import TextEditor as BaseTextEditor
51
logger = logging.getLogger(__name__)
53
#-------------------------------------------------------------------------------
54
# 'SimpleEditor' class:
55
#-------------------------------------------------------------------------------
57
class SimpleEditor ( EditorWithList ):
58
""" Simple style of editor for checklists, which displays a combo box.
61
#---------------------------------------------------------------------------
63
#---------------------------------------------------------------------------
65
# Checklist item names
68
# Checklist item values
71
#---------------------------------------------------------------------------
72
# Finishes initializing the editor by creating the underlying toolkit
74
#---------------------------------------------------------------------------
76
def init ( self, parent ):
77
""" Finishes initializing the editor by creating the underlying toolkit
80
self.create_control( parent )
81
super( SimpleEditor, self ).init( parent )
84
#---------------------------------------------------------------------------
85
# Creates the initial editor control:
86
#---------------------------------------------------------------------------
88
def create_control ( self, parent ):
89
""" Creates the initial editor control.
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 )
95
#---------------------------------------------------------------------------
96
# Handles the list of legal check list values being updated:
97
#---------------------------------------------------------------------------
99
def list_updated ( self, values ):
100
""" Handles updates to the list of legal checklist values.
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 ]
108
# Make sure the current value is still legal:
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:
117
logger.warn('Unable to remove non-current value [%s] from '
118
'values %s', cur_value[i], values)
120
if isinstance( self.value, basestring ):
121
cur_value = ','.join( cur_value )
122
self.value = cur_value
124
self.rebuild_editor()
126
#---------------------------------------------------------------------------
127
# Rebuilds the editor after its definition is modified:
128
#---------------------------------------------------------------------------
130
def rebuild_editor ( self ):
131
""" Rebuilds the editor after its definition is modified.
133
control = self.control
135
for name in self.names:
136
control.Append( name )
140
#----------------------------------------------------------------------------
141
# Handles the user selecting a new value from the combo box:
142
#----------------------------------------------------------------------------
144
def update_object ( self, event ):
145
""" Handles the user selecting a new value from the combo box.
147
value = self.values[ self.names.index( event.GetString() ) ]
148
if type( self.value ) is not str:
153
#---------------------------------------------------------------------------
154
# Updates the editor when the object trait changes external to the editor:
155
#---------------------------------------------------------------------------
157
def update_editor ( self ):
158
""" Updates the editor when the object trait changes externally to the
162
self.control.SetSelection(
163
self.values.index( parse_value( self.value )[0] ) )
167
#-------------------------------------------------------------------------------
168
# 'CustomEditor' class:
169
#-------------------------------------------------------------------------------
171
class CustomEditor ( SimpleEditor ):
172
""" Custom style of editor for checklists, which displays a set of check
176
#---------------------------------------------------------------------------
177
# Creates the initial editor control:
178
#---------------------------------------------------------------------------
180
def create_control ( self, parent ):
181
""" Creates the initial editor control.
183
# Create a panel to hold all of the check boxes
184
self.control = panel = TraitsUIPanel( parent, -1 )
186
#---------------------------------------------------------------------------
187
# Rebuilds the editor after its definition is modified:
188
#---------------------------------------------------------------------------
190
def rebuild_editor ( self ):
191
""" Rebuilds the editor after its definition is modified.
194
panel.SetSizer( None )
195
panel.DestroyChildren()
197
cur_value = parse_value( self.value )
199
# Create a sizer to manage the radio buttons:
203
cols = self.factory.cols
204
rows = (n + cols - 1) / cols
205
incr = [ n / cols ] * cols
208
for i in range( cols ):
210
incr[-1] = -(reduce( lambda x, y: x + y, incr[:-1], 0 ) - 1)
213
sizer = wx.GridSizer( 0, cols, 2, 4 )
215
sizer = wx.BoxSizer( wx.VERTICAL )
217
# Add the set of all possible choices:
219
for i in range( rows ):
220
for j in range( cols ):
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)
230
control = wx.CheckBox( panel, -1, '' )
231
control.Show( False )
233
sizer.Add( control, 0, wx.NORTH, 5 )
235
# Lay out the controls:
236
panel.SetSizerAndFit( sizer )
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 ) )
247
parent = parent.GetParent()
252
#---------------------------------------------------------------------------
253
# Handles the user clicking one of the 'custom' check boxes:
254
#---------------------------------------------------------------------------
256
def update_object ( self, event ):
257
""" Handles the user clicking one of the custom check boxes.
259
control = event.GetEventObject()
260
cur_value = parse_value( self.value )
261
if control.GetValue():
262
cur_value.append( control.value )
264
cur_value.remove( control.value )
265
if isinstance(self.value, basestring):
266
cur_value = ','.join( cur_value )
267
self.value = cur_value
269
#---------------------------------------------------------------------------
270
# Updates the editor when the object trait changes external to the editor:
271
#---------------------------------------------------------------------------
273
def update_editor ( self ):
274
""" Updates the editor when the object trait changes externally to the
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 )
282
#-------------------------------------------------------------------------------
283
# 'TextEditor' class:
284
#-------------------------------------------------------------------------------
286
class TextEditor ( BaseTextEditor ):
287
""" Text style of editor for checklists, which displays a text field.
290
#---------------------------------------------------------------------------
291
# Handles the user changing the contents of the edit control:
292
#---------------------------------------------------------------------------
294
def update_object ( self, event ):
295
""" Handles the user changing the contents of the edit control.
298
value = self.control.GetValue()
299
value = eval( value )
304
except TraitError, excp:
307
#-------------------------------------------------------------------------------
308
# Parse a value into a list:
309
#-------------------------------------------------------------------------------
311
def parse_value ( value ):
312
""" Parses a value into a list.
317
if type( value ) is not str:
320
return [ x.strip() for x in value.split( ',' ) ]
322
### EOF ########################################################################