1
#-------------------------------------------------------------------------------
3
# Copyright (c) 2008, 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 adapter interfaces for use with the ListStrEditor.
21
#-------------------------------------------------------------------------------
23
#-------------------------------------------------------------------------------
25
from __future__ import absolute_import
27
from traits.api import (Any, Bool, Color, Enum, Event, HasPrivateTraits, Int,
28
Interface, List, Str, implements, on_trait_change)
30
#-------------------------------------------------------------------------------
31
# 'IListStrAdapter' interface:
32
#-------------------------------------------------------------------------------
34
class IListStrAdapter ( Interface ):
36
# The index of the current item being adapted:
39
# Current item being adapted:
42
# The current value (if any):
45
# Does the adapter know how to handler the current *item* or not:
48
# Does the value of *accepts* depend only upon the type of *item*?
51
#-------------------------------------------------------------------------------
52
# 'AnIListStrAdapter' class:
53
#-------------------------------------------------------------------------------
55
class AnIListStrAdapter ( HasPrivateTraits ):
57
implements( IListStrAdapter )
59
#-- Implementation of the IListStrAdapter Interface ------------------------
61
# The index of the current item being adapted:
64
# Current item being adapted:
67
# The current value (if any):
70
# Does the adapter know how to handler the current *item* or not:
71
accepts = Bool( True )
73
# Does the value of *accepts* depend only upon the type of *item*?
74
is_cacheable = Bool( True )
76
#-------------------------------------------------------------------------------
77
# 'ListStrAdapter' class:
78
#-------------------------------------------------------------------------------
80
class ListStrAdapter ( HasPrivateTraits ):
81
""" The base class for adapting list items to values that can be edited
85
#-- Trait Definitions ------------------------------------------------------
87
# Specifies the default value for a new list item:
88
default_value = Any( '' )
90
# Specifies the default text for a new list item:
93
# The default text color for list items (even, odd, any rows):
94
even_text_color = Color( None, update = True )
95
odd_text_color = Color( None, update = True )
96
text_color = Color( None, update = True )
98
# The default background color for list items (even, odd, any rows):
99
even_bg_color = Color( None, update = True )
100
odd_bg_color = Color( None, update = True )
101
bg_color = Color( None, update = True )
103
# The name of the default image to use for list items:
104
image = Str( None, update = True )
106
# Can the text value of each list item be edited:
107
can_edit = Bool( True )
109
# Specifies where a dropped item should be placed in the list relative to
110
# the item it is dropped on:
111
dropped = Enum( 'after', 'before' )
113
# The index of the current item being adapter:
116
# The current item being adapted:
119
# The current value (if any):
122
# List of optional delegated adapters:
123
adapters = List( IListStrAdapter, update = True )
125
#-- Private Trait Definitions ----------------------------------------------
127
# Cache of attribute handlers:
130
# Event fired when the cache is flushed:
131
cache_flushed = Event( update = True )
133
#-- Adapter methods that are sensitive to item type ------------------------
135
def get_can_edit ( self, object, trait, index ):
136
""" Returns whether the user can edit a specified *object.trait[index]*
137
list item. A True result indicates the value can be edited, while
138
a False result indicates that it cannot be edited.
140
return self._result_for( 'get_can_edit', object, trait, index )
142
def get_drag ( self, object, trait, index ):
143
""" Returns the 'drag' value for a specified *object.trait[index]*
144
list item. A result of *None* means that the item cannot be dragged.
146
return self._result_for( 'get_drag', object, trait, index )
148
def get_can_drop ( self, object, trait, index, value ):
149
""" Returns whether the specified *value* can be dropped on the
150
specified *object.trait[index]* list item. A value of **True** means
151
the *value* can be dropped; and a value of **False** indicates that
152
it cannot be dropped.
154
return self._result_for( 'get_can_drop', object, trait, index, value )
156
def get_dropped ( self, object, trait, index, value ):
157
""" Returns how to handle a specified *value* being dropped on a
158
specified *object.trait[index]* list item. The possible return
162
Insert the specified *value* before the dropped on item.
164
Insert the specified *value* after the dropped on item.
166
return self._result_for( 'get_dropped', object, trait, index, value )
168
def get_text_color ( self, object, trait, index ):
169
""" Returns the text color for a specified *object.trait[index]* list
170
item. A result of None means use the default list item text color.
172
return self._result_for( 'get_text_color', object, trait, index )
174
def get_bg_color ( self, object, trait, index ):
175
""" Returns the background color for a specified *object.trait[index]*
176
list item. A result of None means use the default list item
179
return self._result_for( 'get_bg_color', object, trait, index )
181
def get_image ( self, object, trait, index ):
182
""" Returns the name of the image to use for a specified
183
*object.trait[index]* list item. A result of None means no image
184
should be used. Otherwise, the result should either be the name of
185
the image, or an ImageResource item specifying the image to use.
187
return self._result_for( 'get_image', object, trait, index )
189
def get_item ( self, object, trait, index ):
190
""" Returns the value of the *object.trait[index]* list item.
192
return self._result_for( 'get_item', object, trait, index )
194
def get_text ( self, object, trait, index ):
195
""" Returns the text to display for a specified *object.trait[index]*
198
return self._result_for( 'get_text', object, trait, index )
200
#-- Adapter methods that are not sensitive to item type --------------------
202
def len ( self, object, trait ):
203
""" Returns the number of items in the specified *object.trait* list.
205
return len( getattr( object, trait ) )
207
def get_default_value ( self, object, trait ):
208
""" Returns a new default value for the specified *object.trait* list.
210
return self.default_value
212
def get_default_text ( self, object, trait ):
213
""" Returns the default text for the specified *object.trait* list.
215
return self.default_text
217
def get_default_image ( self, object, trait ):
218
""" Returns the default image for the specified *object.trait* list.
222
def get_default_bg_color ( self, object, trait ):
223
""" Returns the default background color for the specified
226
return self._get_bg_color()
228
def get_default_text_color ( self, object, trait ):
229
""" Returns the default text color for the specified *object.trait*
232
return self._get_text_color()
234
def set_text ( self, object, trait, index, text ):
235
""" Sets the text for a specified *object.trait[index]* list item to
238
getattr( object, trait )[ index ] = text
240
def delete ( self, object, trait, index ):
241
""" Deletes the specified *object.trait[index]* list item.
243
del getattr( object, trait )[ index ]
245
def insert ( self, object, trait, index, value ):
246
""" Inserts a new value at the specified *object.trait[index]* list
249
getattr( object, trait ) [ index: index ] = [ value ]
251
#-- Private Adapter Implementation Methods ---------------------------------
253
def _get_can_edit ( self ):
256
def _get_drag ( self ):
257
return unicode( self.item )
259
def _get_can_drop ( self ):
260
return isinstance( self.value, basestring )
262
def _get_dropped ( self ):
265
def _get_text_color ( self ):
266
if (self.index % 2) == 0:
267
return self.even_text_color_ or self.text_color_
269
return self.odd_text_color or self.text_color_
271
def _get_bg_color ( self ):
272
if (self.index % 2) == 0:
273
return self.even_bg_color_ or self.bg_color_
275
return self.odd_bg_color or self.bg_color_
277
def _get_image ( self ):
280
def _get_item ( self ):
283
def _get_text ( self ):
284
return unicode( self.item )
286
#-- Private Methods --------------------------------------------------------
288
def _result_for ( self, name, object, trait, index, value = None ):
289
""" Returns/Sets the value of the specified *name* attribute for the
290
specified *object.trait[index]* list item.
294
items = getattr( object, trait )
295
if index >= len( items ):
296
self.item = item = None
298
self.item = item = items[ index ]
300
item_class = item.__class__
301
key = '%s:%s' % ( item_class.__name__, name )
302
handler = self.cache.get( key )
303
if handler is not None:
306
trait_name = name[4:]
308
for adapter in self.adapters:
309
adapter.index = index
311
adapter.value = value
312
if adapter.accepts and (adapter.trait( trait_name ) is not None):
313
handler = lambda: getattr( adapter.set( index = self.index,
314
item = self.item, value = self.value ), trait_name )
316
if adapter.is_cacheable:
321
for klass in item_class.__mro__:
322
cname = '%s_%s' % ( klass.__name__, trait_name )
323
if self.trait( cname ) is not None:
324
handler = lambda: getattr( self, cname )
327
handler = getattr( self, '_' + name )
329
self.cache[ key ] = handler
332
@on_trait_change( 'adapters.+update' )
333
def _flush_cache ( self ):
334
""" Flushes the cache when any trait on any adapter changes.
337
self.cache_flushed = True