~ubuntu-branches/ubuntu/utopic/python-apptools/utopic

« back to all changes in this revision

Viewing changes to enthought/template/test/template_view.py

  • Committer: Bazaar Package Importer
  • Author(s): Varun Hiremath
  • Date: 2011-07-08 23:55:50 UTC
  • mfrom: (2.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110708235550-yz5u79ubeo4dhyfx
Tags: 4.0.0-1
* New upstream release
* Update debian/watch file

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#-------------------------------------------------------------------------------
2
 
#  
3
 
#  A feature-based Traits UI plug-in for viewing templates.
4
 
#  
5
 
#  Written by: David C. Morrill
6
 
#  
7
 
#  Date: 07/30/2007
8
 
#  
9
 
#  (c) Copyright 2007 by Enthought, Inc.
10
 
#  
11
 
#-------------------------------------------------------------------------------
12
 
 
13
 
""" A feature-based Traits UI plug-in for viewing templates.
14
 
"""
15
 
 
16
 
#-------------------------------------------------------------------------------
17
 
#  Imports:
18
 
#-------------------------------------------------------------------------------
19
 
 
20
 
import sys
21
 
 
22
 
from os.path \
23
 
    import split, splitext
24
 
    
25
 
from pickle \
26
 
    import dump, load
27
 
    
28
 
from enthought.traits.api \
29
 
    import HasPrivateTraits, Str, Instance, Any, File, Button, on_trait_change
30
 
    
31
 
from enthought.traits.ui.api \
32
 
    import View, VGroup, HGroup, Tabbed, Item, InstanceEditor, Theme, Label
33
 
    
34
 
from enthought.traits.ui.wx.themed_text_editor \
35
 
    import ThemedTextEditor
36
 
    
37
 
from enthought.developer.features.api \
38
 
    import DropFile
39
 
    
40
 
from enthought.pyface.api \
41
 
    import FileDialog, OK
42
 
    
43
 
from enthought.developer.helper.themes \
44
 
    import TButton
45
 
    
46
 
from enthought.block_canvas.app.utils \
47
 
    import import_log_files
48
 
    
49
 
from enthought.template.api \
50
 
    import ITemplate, ITemplateDataContext, TemplateDataNames, Template
51
 
    
52
 
from enable_editor \
53
 
    import EnableEditor
54
 
 
55
 
#-- Adapters that might be used ------------------------------------------------
56
 
 
57
 
from enthought.template.impl.base_data_context_adapter \
58
 
    import BaseDataContextAdapter
59
 
    
60
 
#-------------------------------------------------------------------------------
61
 
#  Helper class:
62
 
#-------------------------------------------------------------------------------
63
 
 
64
 
class Message ( HasPrivateTraits ):
65
 
    
66
 
    #-- Trait Definitions ------------------------------------------------------
67
 
    
68
 
    # The message to be displayed:
69
 
    message = Str
70
 
    
71
 
    #-- Traits View Definitions ------------------------------------------------
72
 
    
73
 
    view = View(
74
 
        Item( 'message', 
75
 
              style      = 'readonly',
76
 
              show_label = False,
77
 
              editor     = ThemedTextEditor( theme = '@GBB' ),
78
 
        )
79
 
    )
80
 
    
81
 
    #-- Object Overrides -------------------------------------------------------
82
 
    
83
 
    def __init__ ( self, message = '', **traits ):
84
 
        traits.setdefault( 'message', message )
85
 
        
86
 
        super( Message, self ).__init__( **traits )
87
 
        
88
 
# Define some standard messages:
89
 
no_context        = Message( 'Please provide a data context' )
90
 
no_template       = Message( 'Please provide a view template' )
91
 
no_template_found = Message( 'No view templates found in Python source file' )
92
 
no_bindings       = Message( 'Please resolve all required template data bindings' )
93
 
no_options        = Message( 'No options are currently available' )
94
 
    
95
 
#-------------------------------------------------------------------------------
96
 
#  'TemplateView' class:
97
 
#-------------------------------------------------------------------------------
98
 
 
99
 
class TemplateView ( HasPrivateTraits ):
100
 
    """ A feature-based Traits UI plug-in for viewing templates.
101
 
    """
102
 
 
103
 
    #-- Public Traits ----------------------------------------------------------
104
 
 
105
 
    # The name of the plugin:
106
 
    name = Str( 'Template View' )
107
 
    
108
 
    # The data context supplying the data to be viewed:
109
 
    context = Instance( ITemplateDataContext,
110
 
                        connect = 'to: data context' )
111
 
    
112
 
    # The name of the file containing a template view:
113
 
    file_name = File( drop_file = DropFile( 
114
 
                     extensions = [ '.py', '.tv', '.las' ],
115
 
                     tooltip = 'Drop a LAS data file, a saved view template '
116
 
                               'or a Python source file containing a view '
117
 
                               'template here.' ),
118
 
                     connect = 'to: template view' )
119
 
    
120
 
    # The template to view:
121
 
    template = Instance( ITemplate )
122
 
    
123
 
    #-- Private Traits ---------------------------------------------------------
124
 
                     
125
 
    # The name of the file to save the template in:
126
 
    save_file_name = File
127
 
    
128
 
    # The current data names:
129
 
    data_names = Instance( TemplateDataNames )
130
 
    
131
 
    # The TemplateDataNames or Message being viewed:
132
 
    names_view = Any( no_context )
133
 
    
134
 
    # The name of the most recently loaded template file:
135
 
    template_file_name = File
136
 
    
137
 
    # The template or message being viewed:
138
 
    template_view = Any( no_template )
139
 
    
140
 
    # The options view for the currently active template:
141
 
    options_view = Any( no_options )
142
 
    
143
 
    # The event fired when the user wants to save the template:
144
 
    save_template = Button( 'Save Template' )
145
 
    
146
 
    #-- Traits View Definitions ------------------------------------------------
147
 
    
148
 
    view = View(
149
 
        VGroup(
150
 
            HGroup(
151
 
                Item( 'file_name', show_label = False, width = 350 ),
152
 
                TButton( 'save_template',
153
 
                      label        = 'Save Template',
154
 
                      enabled_when = 'template is not None' ),
155
 
                group_theme = Theme( '@GFB', margins = ( -7, -5 ) )
156
 
            ),
157
 
            Tabbed(
158
 
                VGroup(
159
 
                    '8',
160
 
                    Label( 'Data Bindings', 
161
 
                           item_theme = Theme( '@GBB', alignment = 'center' )
162
 
                    ),
163
 
                    Item( 'names_view',
164
 
                          style      = 'custom',
165
 
                          resizable  = True,
166
 
                          editor     = InstanceEditor(),
167
 
                          export     = 'DockWindowShell',
168
 
                          item_theme = Theme( '@GFB', margins = ( -5, -1 ) )
169
 
                    ),
170
 
                    label       = 'Data Bindings',
171
 
                    show_labels = False
172
 
                ),
173
 
                Item( 'template_view',
174
 
                      label     = 'Template View',
175
 
                      style     = 'custom',
176
 
                      resizable = True,
177
 
                      editor    = InstanceEditor( view = 'template_view' ),
178
 
                      export    = 'DockWindowShell'
179
 
                ),
180
 
                Item( 'options_view',
181
 
                      label     = 'Template Options',
182
 
                      style     = 'custom',
183
 
                      resizable = True,
184
 
                      editor    = InstanceEditor( view = 'options_view' ),
185
 
                      export    = 'DockWindowShell'
186
 
                ),
187
 
                id          = 'tabbed',
188
 
                dock        = 'horizontal',
189
 
                show_labels = False
190
 
            ),
191
 
        ),
192
 
        id = 'template.test.template_view.TemplateView'
193
 
    )
194
 
    
195
 
    #-- Trait Event Handlers ---------------------------------------------------
196
 
    
197
 
    def _context_changed ( self, context ):
198
 
        """ Handles the 'context' trait being changed.
199
 
        """
200
 
        if context is None:
201
 
            self.names_view = no_context
202
 
        elif self.template is None:
203
 
            self.names_view = no_template
204
 
        else:
205
 
            self._create_view()
206
 
        
207
 
    def _template_changed ( self, template ):
208
 
        """ Handles the 'template' trait being changed.
209
 
        """
210
 
        if self.context is None:
211
 
            self.template_view = no_context
212
 
        else:
213
 
            self._create_view()
214
 
        
215
 
    def _file_name_changed ( self, file_name ):
216
 
        """ Handles the 'file_name' trait being changed.
217
 
        """
218
 
        ext = splitext( file_name )[1]
219
 
        if ext == '.py':
220
 
            self._load_python_template( file_name )
221
 
        elif ext == '.tv':
222
 
            self._load_pickled_template( file_name )
223
 
        elif ext == '.las':
224
 
            self._load_las_file( file_name )
225
 
        else:
226
 
            # fixme: Display an informational message here...
227
 
            pass
228
 
            
229
 
    def _save_template_changed ( self ):
230
 
        """ Handles the user clicking the 'Save Template' button.
231
 
        """
232
 
        self._save_pickled_template()
233
 
        
234
 
    @on_trait_change( 'data_names.unresolved_data_names' )
235
 
    def _on_unresolved_data_names ( self ):
236
 
        if len( self.data_names.unresolved_data_names ) == 0:
237
 
            self._create_object_view()
238
 
        elif not isinstance( self.template_view, Message ):
239
 
            self.template_view = no_bindings
240
 
            self.options_view  = no_options
241
 
            
242
 
    @on_trait_change( 'template.template_mutated?' )
243
 
    def _on_template_mutated ( self ):
244
 
        """ Handles a mutable template changing.
245
 
        """
246
 
        if self.context is not None:
247
 
            self._create_view()
248
 
        
249
 
    #-- Private Methods --------------------------------------------------------
250
 
    
251
 
    def _load_python_template ( self, file_name ):
252
 
        """ Attempts to load a template from a Python source file.
253
 
        """
254
 
        path, name    = split( file_name )
255
 
        sys.path[0:0] = [ path ]
256
 
        try:
257
 
            ###values = {}
258
 
            module_name, ext = splitext( name )
259
 
            module = __import__( module_name )
260
 
            values = module.__dict__
261
 
            ###execfile( file_name, values )
262
 
            template = values.get( 'template' )
263
 
            if template is None:
264
 
                templates = []
265
 
                for value in values.values():
266
 
                    try:
267
 
                        if (issubclass( value, Template ) and
268
 
                            ###(value.__module__ == '__builtin__')):
269
 
                            (value.__module__ == module_name)):
270
 
                            templates.append( value )
271
 
                    except:
272
 
                        pass
273
 
                        
274
 
                for i, template in enumerate( templates ):
275
 
                    for t in templates[ i + 1: ]:
276
 
                        if issubclass( template, t ):
277
 
                            break
278
 
                    else:
279
 
                        break
280
 
                else:
281
 
                    self.template_view = no_template_found
282
 
                    return
283
 
        
284
 
            if not isinstance( template, Template ):
285
 
                template = template()
286
 
                
287
 
            self.template           = template
288
 
            self.template_file_name = file_name
289
 
            
290
 
        except Exception, excp:
291
 
            self.template_view = Message( str( excp ) )
292
 
            
293
 
        # Clean up the Python path:
294
 
        del sys.path[0]
295
 
        
296
 
    def _load_pickled_template ( self, file_name ):
297
 
        """ Attempts to load a template from a pickle.
298
 
        """
299
 
        # fixme: Implement this...load template from .tv pickle file.
300
 
        fh     = None
301
 
        delete = False
302
 
        try:
303
 
            fh            = open( file_name, 'rb' )
304
 
            file_name     = load( fh )
305
 
            path, name    = split( file_name )
306
 
            sys.path[0:0] = [ path ]
307
 
            delete        = True
308
 
            module_name, ext = splitext( name )
309
 
            module = __import__( module_name )
310
 
            self.template = load( fh )
311
 
            self.template_file_name = file_name
312
 
        except Exception, excp:
313
 
            import traceback
314
 
            traceback.print_exc()
315
 
            self.template_view = Message( str( excp ) )
316
 
            
317
 
        if fh is not None:
318
 
            fh.close()
319
 
            
320
 
        if delete:
321
 
            del sys.path[0]
322
 
        
323
 
    def _load_las_file ( self, file_name ):
324
 
        """ Creates a data context from the specified LAS file.
325
 
        """
326
 
        try:
327
 
            self.context = import_log_files( file_name, 'las' )
328
 
        except Exception, excp:
329
 
            self.names_view = Message( str( excp ) )
330
 
            
331
 
    def _save_pickled_template ( self ):
332
 
        file_name = self.save_file_name or self.file_name
333
 
        fd        = FileDialog(
334
 
                        action       = 'save as',
335
 
                        default_path = file_name )
336
 
                        #wildcard     = 'Template files (*.tv)|*.tv|' )
337
 
        if fd.open() == OK:
338
 
            self.save_file_name = file_name = fd.path
339
 
            fh = None
340
 
            try:
341
 
                fh = open( file_name, 'wb' )
342
 
                dump( self.template_file_name, fh, -1 )
343
 
                dump( self.template.template_from_object(), fh, -1 )
344
 
            except:
345
 
                # fixme: Display an informational message here...
346
 
                import traceback
347
 
                traceback.print_exc()
348
 
                
349
 
            if fh is not None:
350
 
                fh.close()
351
 
        
352
 
    def _create_view ( self ):
353
 
        """ Begins the process of creating a live view from a template and
354
 
            data context object.
355
 
        """
356
 
        self.data_names = self.names_view = nv = TemplateDataNames( 
357
 
                              context    = self.context,
358
 
                              data_names = self.template.names_from_template() )
359
 
                              
360
 
        if len( nv.unresolved_data_names ) == 0:
361
 
            self._create_object_view()
362
 
        else:
363
 
            self.template_view = no_bindings
364
 
            
365
 
    def _create_object_view ( self ):
366
 
        """ Create the object view from the current template.
367
 
        """
368
 
        self.template.object_from_template()
369
 
        self.template_view = self.options_view = self.template
370