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

« back to all changes in this revision

Viewing changes to traitsui/list_str_adapter.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) 2008, 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:   02/29/2008
 
15
#
 
16
#-------------------------------------------------------------------------------
 
17
 
 
18
"""  Defines adapter interfaces for use with the ListStrEditor.
 
19
"""
 
20
 
 
21
#-------------------------------------------------------------------------------
 
22
#  Imports:
 
23
#-------------------------------------------------------------------------------
 
24
 
 
25
from __future__ import absolute_import
 
26
 
 
27
from traits.api import (Any, Bool, Color, Enum, Event, HasPrivateTraits, Int,
 
28
    Interface, List, Str, implements, on_trait_change)
 
29
 
 
30
#-------------------------------------------------------------------------------
 
31
#  'IListStrAdapter' interface:
 
32
#-------------------------------------------------------------------------------
 
33
 
 
34
class IListStrAdapter ( Interface ):
 
35
 
 
36
    # The index of the current item being adapted:
 
37
    index = Int
 
38
 
 
39
    # Current item being adapted:
 
40
    item = Any
 
41
 
 
42
    # The current value (if any):
 
43
    value = Any
 
44
 
 
45
    # Does the adapter know how to handler the current *item* or not:
 
46
    accepts = Bool
 
47
 
 
48
    # Does the value of *accepts* depend only upon the type of *item*?
 
49
    is_cacheable = Bool
 
50
 
 
51
#-------------------------------------------------------------------------------
 
52
#  'AnIListStrAdapter' class:
 
53
#-------------------------------------------------------------------------------
 
54
 
 
55
class AnIListStrAdapter ( HasPrivateTraits ):
 
56
 
 
57
    implements( IListStrAdapter )
 
58
 
 
59
    #-- Implementation of the IListStrAdapter Interface ------------------------
 
60
 
 
61
    # The index of the current item being adapted:
 
62
    index = Int
 
63
 
 
64
    # Current item being adapted:
 
65
    item = Any
 
66
 
 
67
    # The current value (if any):
 
68
    value = Any
 
69
 
 
70
    # Does the adapter know how to handler the current *item* or not:
 
71
    accepts = Bool( True )
 
72
 
 
73
    # Does the value of *accepts* depend only upon the type of *item*?
 
74
    is_cacheable = Bool( True )
 
75
 
 
76
#-------------------------------------------------------------------------------
 
77
#  'ListStrAdapter' class:
 
78
#-------------------------------------------------------------------------------
 
79
 
 
80
class ListStrAdapter ( HasPrivateTraits ):
 
81
    """ The base class for adapting list items to values that can be edited
 
82
        by a ListStrEditor.
 
83
    """
 
84
 
 
85
    #-- Trait Definitions ------------------------------------------------------
 
86
 
 
87
    # Specifies the default value for a new list item:
 
88
    default_value = Any( '' )
 
89
 
 
90
    # Specifies the default text for a new list item:
 
91
    default_text = Str
 
92
 
 
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 )
 
97
 
 
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 )
 
102
 
 
103
    # The name of the default image to use for list items:
 
104
    image = Str( None, update = True )
 
105
 
 
106
    # Can the text value of each list item be edited:
 
107
    can_edit = Bool( True )
 
108
 
 
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' )
 
112
 
 
113
    # The index of the current item being adapter:
 
114
    index = Int
 
115
 
 
116
    # The current item being adapted:
 
117
    item = Any
 
118
 
 
119
    # The current value (if any):
 
120
    value = Any
 
121
 
 
122
    # List of optional delegated adapters:
 
123
    adapters = List( IListStrAdapter, update = True )
 
124
 
 
125
    #-- Private Trait Definitions ----------------------------------------------
 
126
 
 
127
    # Cache of attribute handlers:
 
128
    cache = Any( {} )
 
129
 
 
130
    # Event fired when the cache is flushed:
 
131
    cache_flushed = Event( update = True )
 
132
 
 
133
    #-- Adapter methods that are sensitive to item type ------------------------
 
134
 
 
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.
 
139
        """
 
140
        return self._result_for( 'get_can_edit', object, trait, index )
 
141
 
 
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.
 
145
        """
 
146
        return self._result_for( 'get_drag', object, trait, index )
 
147
 
 
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.
 
153
        """
 
154
        return self._result_for( 'get_can_drop', object, trait, index, value )
 
155
 
 
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
 
159
            values are:
 
160
 
 
161
            'before'
 
162
                Insert the specified *value* before the dropped on item.
 
163
            'after'
 
164
                Insert the specified *value* after the dropped on item.
 
165
        """
 
166
        return self._result_for( 'get_dropped', object, trait, index, value )
 
167
 
 
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.
 
171
        """
 
172
        return self._result_for( 'get_text_color', object, trait, index )
 
173
 
 
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
 
177
            background color.
 
178
        """
 
179
        return self._result_for( 'get_bg_color', object, trait, index )
 
180
 
 
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.
 
186
        """
 
187
        return self._result_for( 'get_image', object, trait, index )
 
188
 
 
189
    def get_item ( self, object, trait, index ):
 
190
        """ Returns the value of the *object.trait[index]* list item.
 
191
        """
 
192
        return self._result_for( 'get_item', object, trait, index )
 
193
 
 
194
    def get_text ( self, object, trait, index ):
 
195
        """ Returns the text to display for a specified *object.trait[index]*
 
196
            list item.
 
197
        """
 
198
        return self._result_for( 'get_text', object, trait, index )
 
199
 
 
200
    #-- Adapter methods that are not sensitive to item type --------------------
 
201
 
 
202
    def len ( self, object, trait ):
 
203
        """ Returns the number of items in the specified *object.trait* list.
 
204
        """
 
205
        return len( getattr( object, trait ) )
 
206
 
 
207
    def get_default_value ( self, object, trait ):
 
208
        """ Returns a new default value for the specified *object.trait* list.
 
209
        """
 
210
        return self.default_value
 
211
 
 
212
    def get_default_text ( self, object, trait ):
 
213
        """ Returns the default text for the specified *object.trait* list.
 
214
        """
 
215
        return self.default_text
 
216
 
 
217
    def get_default_image ( self, object, trait ):
 
218
        """ Returns the default image for the specified *object.trait* list.
 
219
        """
 
220
        return self.image
 
221
 
 
222
    def get_default_bg_color ( self, object, trait ):
 
223
        """ Returns the default background color for the specified
 
224
            *object.trait* list.
 
225
        """
 
226
        return self._get_bg_color()
 
227
 
 
228
    def get_default_text_color ( self, object, trait ):
 
229
        """ Returns the default text color for the specified *object.trait*
 
230
            list.
 
231
        """
 
232
        return self._get_text_color()
 
233
 
 
234
    def set_text ( self, object, trait, index, text ):
 
235
        """ Sets the text for a specified *object.trait[index]* list item to
 
236
            *text*.
 
237
        """
 
238
        getattr( object, trait )[ index ] = text
 
239
 
 
240
    def delete ( self, object, trait, index ):
 
241
        """ Deletes the specified *object.trait[index]* list item.
 
242
        """
 
243
        del getattr( object, trait )[ index ]
 
244
 
 
245
    def insert ( self, object, trait, index, value ):
 
246
        """ Inserts a new value at the specified *object.trait[index]* list
 
247
            index.
 
248
        """
 
249
        getattr( object, trait ) [ index: index ] = [ value ]
 
250
 
 
251
    #-- Private Adapter Implementation Methods ---------------------------------
 
252
 
 
253
    def _get_can_edit ( self ):
 
254
        return self.can_edit
 
255
 
 
256
    def _get_drag ( self ):
 
257
        return unicode( self.item )
 
258
 
 
259
    def _get_can_drop ( self ):
 
260
        return isinstance( self.value, basestring )
 
261
 
 
262
    def _get_dropped ( self ):
 
263
        return self.dropped
 
264
 
 
265
    def _get_text_color ( self ):
 
266
        if (self.index % 2) == 0:
 
267
            return self.even_text_color_ or self.text_color_
 
268
 
 
269
        return self.odd_text_color or self.text_color_
 
270
 
 
271
    def _get_bg_color ( self ):
 
272
        if (self.index % 2) == 0:
 
273
            return self.even_bg_color_ or self.bg_color_
 
274
 
 
275
        return self.odd_bg_color or self.bg_color_
 
276
 
 
277
    def _get_image ( self ):
 
278
        return self.image
 
279
 
 
280
    def _get_item ( self ):
 
281
        return self.item
 
282
 
 
283
    def _get_text ( self ):
 
284
        return unicode( self.item )
 
285
 
 
286
    #-- Private Methods --------------------------------------------------------
 
287
 
 
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.
 
291
        """
 
292
        self.index = index
 
293
        self.value = value
 
294
        items      = getattr( object, trait )
 
295
        if index >= len( items ):
 
296
            self.item = item = None
 
297
        else:
 
298
            self.item = item = items[ index ]
 
299
 
 
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:
 
304
            return handler()
 
305
 
 
306
        trait_name = name[4:]
 
307
 
 
308
        for adapter in self.adapters:
 
309
            adapter.index = index
 
310
            adapter.item  = item
 
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 )
 
315
 
 
316
                if adapter.is_cacheable:
 
317
                    break
 
318
 
 
319
                return handler()
 
320
        else:
 
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 )
 
325
                    break
 
326
            else:
 
327
                handler = getattr( self, '_' + name )
 
328
 
 
329
        self.cache[ key ] = handler
 
330
        return handler()
 
331
 
 
332
    @on_trait_change( 'adapters.+update' )
 
333
    def _flush_cache ( self ):
 
334
        """ Flushes the cache when any trait on any adapter changes.
 
335
        """
 
336
        self.cache = {}
 
337
        self.cache_flushed = True
 
338